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 const GpStringFormat default_drawstring_format
=
41 StringTrimmingCharacter
,
44 StringDigitSubstituteUser
,
53 static GpStringFormat generic_default_format
;
54 static GpStringFormat generic_typographic_format
;
56 void init_generic_string_formats(void)
58 memcpy(&generic_default_format
, &default_drawstring_format
, sizeof(generic_default_format
));
60 memcpy(&generic_typographic_format
, &default_drawstring_format
, sizeof(generic_typographic_format
));
61 generic_typographic_format
.attr
= StringFormatFlagsNoFitBlackBox
| StringFormatFlagsLineLimit
|
62 StringFormatFlagsNoClip
;
63 generic_typographic_format
.trimming
= StringTrimmingNone
;
64 generic_typographic_format
.generic_typographic
= TRUE
;
67 void free_generic_string_formats(void)
69 heap_free(generic_default_format
.character_ranges
);
70 heap_free(generic_default_format
.tabs
);
72 heap_free(generic_typographic_format
.character_ranges
);
73 heap_free(generic_typographic_format
.tabs
);
76 GpStatus WINGDIPAPI
GdipCreateStringFormat(INT attr
, LANGID lang
,
77 GpStringFormat
**format
)
79 TRACE("(%i, %x, %p)\n", attr
, lang
, format
);
82 return InvalidParameter
;
84 *format
= heap_alloc_zero(sizeof(GpStringFormat
));
85 if(!*format
) return OutOfMemory
;
87 (*format
)->attr
= attr
;
88 (*format
)->lang
= lang
;
89 (*format
)->digitlang
= LANG_NEUTRAL
;
90 (*format
)->trimming
= StringTrimmingCharacter
;
91 (*format
)->digitsub
= StringDigitSubstituteUser
;
92 (*format
)->character_ranges
= NULL
;
93 (*format
)->range_count
= 0;
94 (*format
)->generic_typographic
= FALSE
;
96 (*format
)->tabcount
= 0;
97 (*format
)->firsttab
= 0.0;
98 (*format
)->tabs
= NULL
;
100 TRACE("<-- %p\n", *format
);
105 GpStatus WINGDIPAPI
GdipDeleteStringFormat(GpStringFormat
*format
)
108 return InvalidParameter
;
110 if (format
== &generic_default_format
|| format
== &generic_typographic_format
)
113 heap_free(format
->character_ranges
);
114 heap_free(format
->tabs
);
120 GpStatus WINGDIPAPI
GdipStringFormatGetGenericDefault(GpStringFormat
**format
)
123 return InvalidParameter
;
125 *format
= &generic_default_format
;
130 GpStatus WINGDIPAPI
GdipGetStringFormatAlign(GpStringFormat
*format
,
131 StringAlignment
*align
)
133 if(!format
|| !align
)
134 return InvalidParameter
;
136 *align
= format
->align
;
141 GpStatus WINGDIPAPI
GdipGetStringFormatDigitSubstitution(GDIPCONST GpStringFormat
*format
,
142 LANGID
*language
, StringDigitSubstitute
*substitute
)
145 return InvalidParameter
;
147 if(language
) *language
= format
->digitlang
;
148 if(substitute
) *substitute
= format
->digitsub
;
153 GpStatus WINGDIPAPI
GdipGetStringFormatFlags(GDIPCONST GpStringFormat
* format
,
156 if (!(format
&& flags
))
157 return InvalidParameter
;
159 *flags
= format
->attr
;
164 GpStatus WINGDIPAPI
GdipGetStringFormatHotkeyPrefix(GDIPCONST GpStringFormat
168 return InvalidParameter
;
170 *hkpx
= (INT
)format
->hkprefix
;
175 GpStatus WINGDIPAPI
GdipGetStringFormatLineAlign(GpStringFormat
*format
,
176 StringAlignment
*align
)
178 if(!format
|| !align
)
179 return InvalidParameter
;
181 *align
= format
->line_align
;
186 GpStatus WINGDIPAPI
GdipGetStringFormatMeasurableCharacterRangeCount(
187 GDIPCONST GpStringFormat
*format
, INT
*count
)
189 if (!(format
&& count
))
190 return InvalidParameter
;
192 TRACE("%p %p\n", format
, count
);
194 *count
= format
->range_count
;
199 GpStatus WINGDIPAPI
GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat
*format
,
202 if(!format
|| !count
)
203 return InvalidParameter
;
205 *count
= format
->tabcount
;
210 GpStatus WINGDIPAPI
GdipGetStringFormatTabStops(GDIPCONST GpStringFormat
*format
, INT count
,
211 REAL
*firsttab
, REAL
*tabs
)
213 if(!format
|| !firsttab
|| !tabs
)
214 return InvalidParameter
;
216 /* native simply crashes on count < 0 */
218 memcpy(tabs
, format
->tabs
, sizeof(REAL
)*count
);
220 *firsttab
= format
->firsttab
;
225 GpStatus WINGDIPAPI
GdipGetStringFormatTrimming(GpStringFormat
*format
,
226 StringTrimming
*trimming
)
228 if(!format
|| !trimming
)
229 return InvalidParameter
;
231 *trimming
= format
->trimming
;
236 GpStatus WINGDIPAPI
GdipSetStringFormatAlign(GpStringFormat
*format
,
237 StringAlignment align
)
239 TRACE("(%p, %i)\n", format
, align
);
242 return InvalidParameter
;
244 format
->align
= align
;
249 /*FIXME: digit substitution actually not implemented, get/set only */
250 GpStatus WINGDIPAPI
GdipSetStringFormatDigitSubstitution(GpStringFormat
*format
,
251 LANGID language
, StringDigitSubstitute substitute
)
253 TRACE("(%p, %x, %i)\n", format
, language
, substitute
);
256 return InvalidParameter
;
258 format
->digitlang
= language
;
259 format
->digitsub
= substitute
;
264 GpStatus WINGDIPAPI
GdipSetStringFormatHotkeyPrefix(GpStringFormat
*format
,
267 TRACE("(%p, %i)\n", format
, hkpx
);
269 if(!format
|| hkpx
< 0 || hkpx
> 2)
270 return InvalidParameter
;
272 format
->hkprefix
= (HotkeyPrefix
) hkpx
;
277 GpStatus WINGDIPAPI
GdipSetStringFormatLineAlign(GpStringFormat
*format
,
278 StringAlignment align
)
280 TRACE("(%p, %i)\n", format
, align
);
283 return InvalidParameter
;
285 format
->line_align
= align
;
290 GpStatus WINGDIPAPI
GdipSetStringFormatMeasurableCharacterRanges(
291 GpStringFormat
*format
, INT rangeCount
, GDIPCONST CharacterRange
*ranges
)
293 CharacterRange
*new_ranges
;
295 if (!(format
&& ranges
))
296 return InvalidParameter
;
298 TRACE("%p, %d, %p\n", format
, rangeCount
, ranges
);
300 new_ranges
= heap_alloc_zero(rangeCount
* sizeof(CharacterRange
));
304 heap_free(format
->character_ranges
);
305 format
->character_ranges
= new_ranges
;
306 memcpy(format
->character_ranges
, ranges
, sizeof(CharacterRange
) * rangeCount
);
307 format
->range_count
= rangeCount
;
312 GpStatus WINGDIPAPI
GdipSetStringFormatTabStops(GpStringFormat
*format
, REAL firsttab
,
313 INT count
, GDIPCONST REAL
*tabs
)
315 TRACE("(%p, %0.2f, %i, %p)\n", format
, firsttab
, count
, tabs
);
318 return InvalidParameter
;
321 if(firsttab
< 0.0) return NotImplemented
;
322 /* first time allocation */
323 if(format
->tabcount
== 0){
324 format
->tabs
= heap_alloc_zero(sizeof(REAL
)*count
);
329 if((format
->tabcount
< count
) && (format
->tabcount
> 0)){
331 ptr
= heap_realloc(format
->tabs
, sizeof(REAL
)*count
);
336 format
->firsttab
= firsttab
;
337 format
->tabcount
= count
;
338 memcpy(format
->tabs
, tabs
, sizeof(REAL
)*count
);
344 GpStatus WINGDIPAPI
GdipSetStringFormatTrimming(GpStringFormat
*format
,
345 StringTrimming trimming
)
347 TRACE("(%p, %i)\n", format
, trimming
);
350 return InvalidParameter
;
352 format
->trimming
= trimming
;
357 GpStatus WINGDIPAPI
GdipSetStringFormatFlags(GpStringFormat
*format
, INT flags
)
359 TRACE("(%p, %x)\n", format
, flags
);
362 return InvalidParameter
;
364 format
->attr
= flags
;
369 GpStatus WINGDIPAPI
GdipCloneStringFormat(GDIPCONST GpStringFormat
*format
, GpStringFormat
**newFormat
)
371 if(!format
|| !newFormat
)
372 return InvalidParameter
;
374 *newFormat
= heap_alloc_zero(sizeof(GpStringFormat
));
375 if(!*newFormat
) return OutOfMemory
;
377 **newFormat
= *format
;
379 if(format
->tabcount
> 0){
380 (*newFormat
)->tabs
= heap_alloc_zero(sizeof(REAL
) * format
->tabcount
);
381 if(!(*newFormat
)->tabs
){
382 heap_free(*newFormat
);
385 memcpy((*newFormat
)->tabs
, format
->tabs
, sizeof(REAL
) * format
->tabcount
);
388 (*newFormat
)->tabs
= NULL
;
390 if(format
->range_count
> 0){
391 (*newFormat
)->character_ranges
= heap_alloc_zero(sizeof(CharacterRange
) * format
->range_count
);
392 if(!(*newFormat
)->character_ranges
){
393 heap_free((*newFormat
)->tabs
);
394 heap_free(*newFormat
);
397 memcpy((*newFormat
)->character_ranges
, format
->character_ranges
,
398 sizeof(CharacterRange
) * format
->range_count
);
401 (*newFormat
)->character_ranges
= NULL
;
403 TRACE("%p %p\n",format
,newFormat
);
408 GpStatus WINGDIPAPI
GdipStringFormatGetGenericTypographic(GpStringFormat
**format
)
411 return InvalidParameter
;
413 *format
= &generic_typographic_format
;
415 TRACE("%p => %p\n", format
, *format
);