push 7bb4e6a724086e39bb3a77eb03fa4dcdb495b071
[wine/hacks.git] / dlls / gdiplus / stringformat.c
blobbfe7d34e05ef05043545b3eafd51f493f4270e3b
1 /*
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
20 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "wingdi.h"
25 #include "winnls.h"
27 #include "objbase.h"
29 #include "gdiplus.h"
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);
40 if(!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 /* tabstops */
52 (*format)->tabcount = 0;
53 (*format)->firsttab = 0.0;
54 (*format)->tabs = NULL;
56 return Ok;
59 GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat *format)
61 if(!format)
62 return InvalidParameter;
64 GdipFree(format->tabs);
65 GdipFree(format);
67 return Ok;
70 GpStatus WINGDIPAPI GdipStringFormatGetGenericDefault(GpStringFormat **format)
72 GpStatus stat;
74 if (!format)
75 return InvalidParameter;
77 stat = GdipCreateStringFormat(0, LANG_NEUTRAL, format);
78 if(stat != Ok)
79 return stat;
81 (*format)->align = StringAlignmentNear;
82 (*format)->vertalign = StringAlignmentNear;
84 return Ok;
87 GpStatus WINGDIPAPI GdipGetStringFormatAlign(GpStringFormat *format,
88 StringAlignment *align)
90 if(!format || !align)
91 return InvalidParameter;
93 *align = format->align;
95 return Ok;
98 GpStatus WINGDIPAPI GdipGetStringFormatDigitSubstitution(GDIPCONST GpStringFormat *format,
99 LANGID *language, StringDigitSubstitute *substitute)
101 if(!format)
102 return InvalidParameter;
104 if(language) *language = format->digitlang;
105 if(substitute) *substitute = format->digitsub;
107 return Ok;
110 GpStatus WINGDIPAPI GdipGetStringFormatFlags(GDIPCONST GpStringFormat* format,
111 INT* flags)
113 if (!(format && flags))
114 return InvalidParameter;
116 *flags = format->attr;
118 return Ok;
121 GpStatus WINGDIPAPI GdipGetStringFormatHotkeyPrefix(GDIPCONST GpStringFormat
122 *format, INT *hkpx)
124 if(!format || !hkpx)
125 return InvalidParameter;
127 *hkpx = (INT)format->hkprefix;
129 return Ok;
132 GpStatus WINGDIPAPI GdipGetStringFormatLineAlign(GpStringFormat *format,
133 StringAlignment *align)
135 if(!format || !align)
136 return InvalidParameter;
138 *align = format->vertalign;
140 return Ok;
143 GpStatus WINGDIPAPI GdipGetStringFormatMeasurableCharacterRangeCount(
144 GDIPCONST GpStringFormat* format, INT* count)
146 if (!(format && count))
147 return InvalidParameter;
149 FIXME("stub: %p %p\n", format, count);
151 return NotImplemented;
154 GpStatus WINGDIPAPI GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat *format,
155 INT *count)
157 if(!format || !count)
158 return InvalidParameter;
160 *count = format->tabcount;
162 return Ok;
165 GpStatus WINGDIPAPI GdipGetStringFormatTabStops(GDIPCONST GpStringFormat *format, INT count,
166 REAL *firsttab, REAL *tabs)
168 if(!format || !firsttab || !tabs)
169 return InvalidParameter;
171 /* native simply crashes on count < 0 */
172 if(count != 0)
173 memcpy(tabs, format->tabs, sizeof(REAL)*count);
175 *firsttab = format->firsttab;
177 return Ok;
180 GpStatus WINGDIPAPI GdipGetStringFormatTrimming(GpStringFormat *format,
181 StringTrimming *trimming)
183 if(!format || !trimming)
184 return InvalidParameter;
186 *trimming = format->trimming;
188 return Ok;
191 GpStatus WINGDIPAPI GdipSetStringFormatAlign(GpStringFormat *format,
192 StringAlignment align)
194 TRACE("(%p, %i)\n", format, align);
196 if(!format)
197 return InvalidParameter;
199 format->align = align;
201 return Ok;
204 /*FIXME: digit substitution actually not implemented, get/set only */
205 GpStatus WINGDIPAPI GdipSetStringFormatDigitSubstitution(GpStringFormat *format,
206 LANGID language, StringDigitSubstitute substitute)
208 TRACE("(%p, %x, %i)\n", format, language, substitute);
210 if(!format)
211 return InvalidParameter;
213 format->digitlang = language;
214 format->digitsub = substitute;
216 return Ok;
219 GpStatus WINGDIPAPI GdipSetStringFormatHotkeyPrefix(GpStringFormat *format,
220 INT hkpx)
222 TRACE("(%p, %i)\n", format, hkpx);
224 if(!format || hkpx < 0 || hkpx > 2)
225 return InvalidParameter;
227 format->hkprefix = (HotkeyPrefix) hkpx;
229 return Ok;
232 GpStatus WINGDIPAPI GdipSetStringFormatLineAlign(GpStringFormat *format,
233 StringAlignment align)
235 TRACE("(%p, %i)\n", format, align);
237 if(!format)
238 return InvalidParameter;
240 format->vertalign = align;
242 return Ok;
245 GpStatus WINGDIPAPI GdipSetStringFormatMeasurableCharacterRanges(GpStringFormat*
246 format, INT rangeCount, GDIPCONST CharacterRange* ranges)
248 if (!(format && rangeCount && ranges))
249 return InvalidParameter;
251 FIXME("stub: %p, %d, %p\n", format, rangeCount, ranges);
253 return NotImplemented;
256 GpStatus WINGDIPAPI GdipSetStringFormatTabStops(GpStringFormat *format, REAL firsttab,
257 INT count, GDIPCONST REAL *tabs)
259 TRACE("(%p, %0.2f, %i, %p)\n", format, firsttab, count, tabs);
261 if(!format || !tabs)
262 return InvalidParameter;
264 if(count > 0){
265 if(firsttab < 0.0) return NotImplemented;
266 /* first time allocation */
267 if(format->tabcount == 0){
268 format->tabs = GdipAlloc(sizeof(REAL)*count);
269 if(!format->tabs)
270 return OutOfMemory;
272 /* reallocation */
273 if((format->tabcount < count) && (format->tabcount > 0)){
274 REAL *ptr;
275 ptr = HeapReAlloc(GetProcessHeap(), 0, format->tabs, sizeof(REAL)*count);
276 if(!ptr)
277 return OutOfMemory;
278 format->tabs = ptr;
280 format->firsttab = firsttab;
281 format->tabcount = count;
282 memcpy(format->tabs, tabs, sizeof(REAL)*count);
285 return Ok;
288 GpStatus WINGDIPAPI GdipSetStringFormatTrimming(GpStringFormat *format,
289 StringTrimming trimming)
291 TRACE("(%p, %i)\n", format, trimming);
293 if(!format)
294 return InvalidParameter;
296 format->trimming = trimming;
298 return Ok;
301 GpStatus WINGDIPAPI GdipSetStringFormatFlags(GpStringFormat *format, INT flags)
303 TRACE("(%p, %x)\n", format, flags);
305 if(!format)
306 return InvalidParameter;
308 format->attr = flags;
310 return Ok;
313 GpStatus WINGDIPAPI GdipCloneStringFormat(GDIPCONST GpStringFormat *format, GpStringFormat **newFormat)
315 if(!format || !newFormat)
316 return InvalidParameter;
318 *newFormat = GdipAlloc(sizeof(GpStringFormat));
319 if(!*newFormat) return OutOfMemory;
321 **newFormat = *format;
323 if(format->tabcount > 0){
324 (*newFormat)->tabs = GdipAlloc(sizeof(REAL) * format->tabcount);
325 if(!(*newFormat)->tabs){
326 GdipFree(*newFormat);
327 return OutOfMemory;
329 memcpy((*newFormat)->tabs, format->tabs, sizeof(REAL) * format->tabcount);
331 else
332 (*newFormat)->tabs = NULL;
334 TRACE("%p %p\n",format,newFormat);
336 return Ok;
339 GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **format)
341 GpStatus stat;
343 if(!format)
344 return InvalidParameter;
346 stat = GdipCreateStringFormat(StringFormatFlagsNoFitBlackBox |
347 StringFormatFlagsLineLimit |
348 StringFormatFlagsNoClip, LANG_NEUTRAL, format);
349 if(stat != Ok)
350 return stat;
352 (*format)->digitlang = LANG_NEUTRAL;
353 (*format)->digitsub = StringDigitSubstituteUser;
354 (*format)->trimming = StringTrimmingNone;
355 (*format)->hkprefix = HotkeyPrefixNone;
356 (*format)->align = StringAlignmentNear;
357 (*format)->vertalign = StringAlignmentNear;
359 return Ok;