3 * Copyright (C) 2007 Google (Evan Stade)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "gdiplus_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus
);
35 GpStatus WINGDIPAPI
GdipCreateStringFormat(INT attr
, LANGID lang
,
36 GpStringFormat
**format
)
38 TRACE("(%i, %x, %p)\n", attr
, lang
, format
);
41 return InvalidParameter
;
43 *format
= GdipAlloc(sizeof(GpStringFormat
));
44 if(!*format
) return OutOfMemory
;
46 (*format
)->attr
= attr
;
47 (*format
)->lang
= lang
;
48 (*format
)->digitlang
= LANG_NEUTRAL
;
49 (*format
)->trimming
= StringTrimmingCharacter
;
50 (*format
)->digitsub
= StringDigitSubstituteUser
;
51 (*format
)->character_ranges
= NULL
;
52 (*format
)->range_count
= 0;
53 (*format
)->generic_typographic
= FALSE
;
55 (*format
)->tabcount
= 0;
56 (*format
)->firsttab
= 0.0;
57 (*format
)->tabs
= NULL
;
59 TRACE("<-- %p\n", *format
);
64 GpStatus WINGDIPAPI
GdipDeleteStringFormat(GpStringFormat
*format
)
67 return InvalidParameter
;
69 GdipFree(format
->character_ranges
);
70 GdipFree(format
->tabs
);
76 GpStatus WINGDIPAPI
GdipStringFormatGetGenericDefault(GpStringFormat
**format
)
81 return InvalidParameter
;
83 stat
= GdipCreateStringFormat(0, LANG_NEUTRAL
, format
);
87 (*format
)->align
= StringAlignmentNear
;
88 (*format
)->vertalign
= StringAlignmentNear
;
93 GpStatus WINGDIPAPI
GdipGetStringFormatAlign(GpStringFormat
*format
,
94 StringAlignment
*align
)
97 return InvalidParameter
;
99 *align
= format
->align
;
104 GpStatus WINGDIPAPI
GdipGetStringFormatDigitSubstitution(GDIPCONST GpStringFormat
*format
,
105 LANGID
*language
, StringDigitSubstitute
*substitute
)
108 return InvalidParameter
;
110 if(language
) *language
= format
->digitlang
;
111 if(substitute
) *substitute
= format
->digitsub
;
116 GpStatus WINGDIPAPI
GdipGetStringFormatFlags(GDIPCONST GpStringFormat
* format
,
119 if (!(format
&& flags
))
120 return InvalidParameter
;
122 *flags
= format
->attr
;
127 GpStatus WINGDIPAPI
GdipGetStringFormatHotkeyPrefix(GDIPCONST GpStringFormat
131 return InvalidParameter
;
133 *hkpx
= (INT
)format
->hkprefix
;
138 GpStatus WINGDIPAPI
GdipGetStringFormatLineAlign(GpStringFormat
*format
,
139 StringAlignment
*align
)
141 if(!format
|| !align
)
142 return InvalidParameter
;
144 *align
= format
->vertalign
;
149 GpStatus WINGDIPAPI
GdipGetStringFormatMeasurableCharacterRangeCount(
150 GDIPCONST GpStringFormat
*format
, INT
*count
)
152 if (!(format
&& count
))
153 return InvalidParameter
;
155 TRACE("%p %p\n", format
, count
);
157 *count
= format
->range_count
;
162 GpStatus WINGDIPAPI
GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat
*format
,
165 if(!format
|| !count
)
166 return InvalidParameter
;
168 *count
= format
->tabcount
;
173 GpStatus WINGDIPAPI
GdipGetStringFormatTabStops(GDIPCONST GpStringFormat
*format
, INT count
,
174 REAL
*firsttab
, REAL
*tabs
)
176 if(!format
|| !firsttab
|| !tabs
)
177 return InvalidParameter
;
179 /* native simply crashes on count < 0 */
181 memcpy(tabs
, format
->tabs
, sizeof(REAL
)*count
);
183 *firsttab
= format
->firsttab
;
188 GpStatus WINGDIPAPI
GdipGetStringFormatTrimming(GpStringFormat
*format
,
189 StringTrimming
*trimming
)
191 if(!format
|| !trimming
)
192 return InvalidParameter
;
194 *trimming
= format
->trimming
;
199 GpStatus WINGDIPAPI
GdipSetStringFormatAlign(GpStringFormat
*format
,
200 StringAlignment align
)
202 TRACE("(%p, %i)\n", format
, align
);
205 return InvalidParameter
;
207 format
->align
= align
;
212 /*FIXME: digit substitution actually not implemented, get/set only */
213 GpStatus WINGDIPAPI
GdipSetStringFormatDigitSubstitution(GpStringFormat
*format
,
214 LANGID language
, StringDigitSubstitute substitute
)
216 TRACE("(%p, %x, %i)\n", format
, language
, substitute
);
219 return InvalidParameter
;
221 format
->digitlang
= language
;
222 format
->digitsub
= substitute
;
227 GpStatus WINGDIPAPI
GdipSetStringFormatHotkeyPrefix(GpStringFormat
*format
,
230 TRACE("(%p, %i)\n", format
, hkpx
);
232 if(!format
|| hkpx
< 0 || hkpx
> 2)
233 return InvalidParameter
;
235 format
->hkprefix
= (HotkeyPrefix
) hkpx
;
240 GpStatus WINGDIPAPI
GdipSetStringFormatLineAlign(GpStringFormat
*format
,
241 StringAlignment align
)
243 TRACE("(%p, %i)\n", format
, align
);
246 return InvalidParameter
;
248 format
->vertalign
= align
;
253 GpStatus WINGDIPAPI
GdipSetStringFormatMeasurableCharacterRanges(
254 GpStringFormat
*format
, INT rangeCount
, GDIPCONST CharacterRange
*ranges
)
256 CharacterRange
*new_ranges
;
258 if (!(format
&& ranges
))
259 return InvalidParameter
;
261 TRACE("%p, %d, %p\n", format
, rangeCount
, ranges
);
263 new_ranges
= GdipAlloc(rangeCount
* sizeof(CharacterRange
));
267 GdipFree(format
->character_ranges
);
268 format
->character_ranges
= new_ranges
;
269 memcpy(format
->character_ranges
, ranges
, sizeof(CharacterRange
) * rangeCount
);
270 format
->range_count
= rangeCount
;
275 GpStatus WINGDIPAPI
GdipSetStringFormatTabStops(GpStringFormat
*format
, REAL firsttab
,
276 INT count
, GDIPCONST REAL
*tabs
)
278 TRACE("(%p, %0.2f, %i, %p)\n", format
, firsttab
, count
, tabs
);
281 return InvalidParameter
;
284 if(firsttab
< 0.0) return NotImplemented
;
285 /* first time allocation */
286 if(format
->tabcount
== 0){
287 format
->tabs
= GdipAlloc(sizeof(REAL
)*count
);
292 if((format
->tabcount
< count
) && (format
->tabcount
> 0)){
294 ptr
= HeapReAlloc(GetProcessHeap(), 0, format
->tabs
, sizeof(REAL
)*count
);
299 format
->firsttab
= firsttab
;
300 format
->tabcount
= count
;
301 memcpy(format
->tabs
, tabs
, sizeof(REAL
)*count
);
307 GpStatus WINGDIPAPI
GdipSetStringFormatTrimming(GpStringFormat
*format
,
308 StringTrimming trimming
)
310 TRACE("(%p, %i)\n", format
, trimming
);
313 return InvalidParameter
;
315 format
->trimming
= trimming
;
320 GpStatus WINGDIPAPI
GdipSetStringFormatFlags(GpStringFormat
*format
, INT flags
)
322 TRACE("(%p, %x)\n", format
, flags
);
325 return InvalidParameter
;
327 format
->attr
= flags
;
332 GpStatus WINGDIPAPI
GdipCloneStringFormat(GDIPCONST GpStringFormat
*format
, GpStringFormat
**newFormat
)
334 if(!format
|| !newFormat
)
335 return InvalidParameter
;
337 *newFormat
= GdipAlloc(sizeof(GpStringFormat
));
338 if(!*newFormat
) return OutOfMemory
;
340 **newFormat
= *format
;
342 if(format
->tabcount
> 0){
343 (*newFormat
)->tabs
= GdipAlloc(sizeof(REAL
) * format
->tabcount
);
344 if(!(*newFormat
)->tabs
){
345 GdipFree(*newFormat
);
348 memcpy((*newFormat
)->tabs
, format
->tabs
, sizeof(REAL
) * format
->tabcount
);
351 (*newFormat
)->tabs
= NULL
;
353 if(format
->range_count
> 0){
354 (*newFormat
)->character_ranges
= GdipAlloc(sizeof(CharacterRange
) * format
->range_count
);
355 if(!(*newFormat
)->character_ranges
){
356 GdipFree((*newFormat
)->tabs
);
357 GdipFree(*newFormat
);
360 memcpy((*newFormat
)->character_ranges
, format
->character_ranges
,
361 sizeof(CharacterRange
) * format
->range_count
);
364 (*newFormat
)->character_ranges
= NULL
;
366 TRACE("%p %p\n",format
,newFormat
);
371 GpStatus WINGDIPAPI
GdipStringFormatGetGenericTypographic(GpStringFormat
**format
)
376 return InvalidParameter
;
378 stat
= GdipCreateStringFormat(StringFormatFlagsNoFitBlackBox
|
379 StringFormatFlagsLineLimit
|
380 StringFormatFlagsNoClip
, LANG_NEUTRAL
, format
);
384 (*format
)->digitlang
= LANG_NEUTRAL
;
385 (*format
)->digitsub
= StringDigitSubstituteUser
;
386 (*format
)->trimming
= StringTrimmingNone
;
387 (*format
)->hkprefix
= HotkeyPrefixNone
;
388 (*format
)->align
= StringAlignmentNear
;
389 (*format
)->vertalign
= StringAlignmentNear
;
390 (*format
)->generic_typographic
= TRUE
;
392 TRACE("%p => %p\n", format
, *format
);