1/**************************************************************************\
2*
3* Copyright (c) 1998-2000, Microsoft Corp.  All Rights Reserved.
4*
5* Module Name:
6*
7*   GdiplusStringFormat.h
8*
9* Abstract:
10*
11*   String format specification for DrawString and text APIs
12*
13\**************************************************************************/
14
15#ifndef _GDIPLUSSTRINGFORMAT_H
16#define _GDIPLUSSTRINGFORMAT_H
17
18
19class StringFormat : public GdiplusBase
20{
21public:
22    friend class Graphics;
23    friend class GraphicsPath;
24
25
26    StringFormat(
27        IN INT     formatFlags = 0,
28        IN LANGID  language = LANG_NEUTRAL
29    )
30    {
31        nativeFormat = NULL;
32        lastError = DllExports::GdipCreateStringFormat(
33            formatFlags,
34            language,
35            &nativeFormat
36        );
37    }
38
39    static const StringFormat *GenericDefault();
40    static const StringFormat *GenericTypographic();
41
42    // Constructor based on existing string format
43
44    StringFormat(
45        IN const StringFormat *format
46    )
47    {
48        nativeFormat = NULL;
49        lastError = DllExports::GdipCloneStringFormat(
50            format ? format->nativeFormat : NULL,
51            &nativeFormat
52        );
53    }
54
55    StringFormat *Clone() const
56    {
57        GpStringFormat *clonedStringFormat = NULL;
58
59        lastError = DllExports::GdipCloneStringFormat(
60            nativeFormat,
61            &clonedStringFormat
62        );
63
64        if (lastError == Ok)
65            return new StringFormat(clonedStringFormat, lastError);
66        else
67            return NULL;
68    }
69
70    ~StringFormat()
71    {
72        DllExports::GdipDeleteStringFormat(nativeFormat);
73    }
74
75    Status SetFormatFlags(IN INT flags)
76    {
77        return SetStatus(DllExports::GdipSetStringFormatFlags(
78            nativeFormat,
79            flags
80        ));
81    }
82
83    INT GetFormatFlags() const
84    {
85        INT flags;
86        SetStatus(DllExports::GdipGetStringFormatFlags(nativeFormat, &flags));
87        return flags;
88    }
89
90#ifndef DCR_USE_NEW_152154
91    Status SetLineSpacing(
92        IN REAL        amount = 1.0f,
93        IN LineSpacing method = LineSpacingRecommended
94    )
95    {
96        return SetStatus(DllExports::GdipSetStringFormatLineSpacing(
97            nativeFormat,
98            amount,
99            method
100        ));
101    }
102#endif
103
104    Status SetAlignment(IN StringAlignment align)
105    {
106        return SetStatus(DllExports::GdipSetStringFormatAlign(
107            nativeFormat,
108            align
109        ));
110    }
111
112    StringAlignment GetAlignment() const
113    {
114        StringAlignment alignment;
115        SetStatus(DllExports::GdipGetStringFormatAlign(
116            nativeFormat,
117            &alignment
118        ));
119        return alignment;
120    }
121
122    Status SetLineAlignment(IN StringAlignment align)
123    {
124        return SetStatus(DllExports::GdipSetStringFormatLineAlign(
125            nativeFormat,
126            align
127        ));
128    }
129
130    StringAlignment GetLineAlignment() const
131    {
132        StringAlignment alignment;
133        SetStatus(DllExports::GdipGetStringFormatLineAlign(
134            nativeFormat,
135            &alignment
136        ));
137        return alignment;
138    }
139
140    Status SetHotkeyPrefix(IN HotkeyPrefix hotkeyPrefix)
141    {
142        return SetStatus(DllExports::GdipSetStringFormatHotkeyPrefix(
143            nativeFormat,
144            (INT)hotkeyPrefix
145        ));
146    }
147
148    HotkeyPrefix GetHotkeyPrefix() const
149    {
150        HotkeyPrefix hotkeyPrefix;
151        SetStatus(DllExports::GdipGetStringFormatHotkeyPrefix(
152            nativeFormat,
153            (INT*)&hotkeyPrefix
154        ));
155        return hotkeyPrefix;
156    }
157
158    Status SetTabStops(
159        IN REAL    firstTabOffset,
160        IN INT     count,
161        IN const REAL    *tabStops
162    )
163    {
164        return SetStatus(DllExports::GdipSetStringFormatTabStops(
165            nativeFormat,
166            firstTabOffset,
167            count,
168            tabStops
169        ));
170    }
171
172    INT GetTabStopCount() const
173    {
174        INT count;
175        SetStatus(DllExports::GdipGetStringFormatTabStopCount(nativeFormat, &count));
176        return count;
177    }
178
179    Status GetTabStops(
180        IN INT     count,
181        OUT REAL   *firstTabOffset,
182        OUT REAL   *tabStops
183    ) const
184    {
185        return SetStatus(DllExports::GdipGetStringFormatTabStops(
186            nativeFormat,
187            count,
188            firstTabOffset,
189            tabStops
190        ));
191    }
192
193#ifdef DCR_USE_NEW_146933
194    Status SetDigitSubstitution(
195        IN LANGID                language,
196        IN StringDigitSubstitute substitute
197    )
198    {
199        return SetStatus(DllExports::GdipSetStringFormatDigitSubstitution(
200            nativeFormat,
201            language,
202            substitute
203        ));
204    }
205
206    LANGID GetDigitSubstitutionLanguage(
207    ) const
208    {
209        LANGID language;
210        SetStatus(DllExports::GdipGetStringFormatDigitSubstitution(
211            nativeFormat,
212            &language,
213            NULL
214        ));
215        return language;
216    }
217
218    StringDigitSubstitute GetDigitSubstitutionMethod(
219    ) const
220    {
221        StringDigitSubstitute substitute;
222        SetStatus(DllExports::GdipGetStringFormatDigitSubstitution(
223            nativeFormat,
224            NULL,
225            &substitute
226        ));
227        return substitute;
228    }
229#endif // DCR_USE_NEW_146933
230
231    // String trimming. How to handle more text than can be displayed
232    // in the limits available.
233
234    Status SetTrimming(IN StringTrimming trimming)
235    {
236        return SetStatus(DllExports::GdipSetStringFormatTrimming(
237            nativeFormat,
238            trimming
239        ));
240    }
241
242    StringTrimming StringFormat::GetTrimming() const
243    {
244        StringTrimming trimming;
245        SetStatus(DllExports::GdipGetStringFormatTrimming(
246            nativeFormat,
247            &trimming
248        ));
249        return trimming;
250    }
251
252#ifdef DCR_USE_NEW_174340
253    Status SetMeasurableCharacterRanges(
254        IN INT                  rangeCount,
255        IN const CharacterRange *ranges
256    )
257    {
258        return SetStatus(DllExports::GdipSetStringFormatMeasurableCharacterRanges(
259            nativeFormat,
260            rangeCount,
261            ranges
262        ));
263    }
264
265    INT GetMeasurableCharacterRangeCount()
266    {
267        INT count;
268        SetStatus(DllExports::GdipGetStringFormatMeasurableCharacterRangeCount(
269            nativeFormat,
270            &count
271        ));
272        return count;
273    }
274#endif
275
276    // GetLastStatus - return last error code and clear error code
277
278    Status GetLastStatus() const
279    {
280        Status lastStatus = lastError;
281        lastError = Ok;
282
283        return lastStatus;
284    }
285
286protected:
287
288    Status SetStatus(GpStatus newStatus) const
289    {
290        if (newStatus == Ok)
291        {
292            return Ok;
293        }
294        else
295        {
296            return lastError = newStatus;
297        }
298    }
299
300
301// Not allowed and move to private
302    StringFormat(const StringFormat &source)
303    {
304        nativeFormat = NULL;
305        lastError = DllExports::GdipCloneStringFormat(
306            source.nativeFormat,
307            &nativeFormat
308        );
309    }
310
311    StringFormat& operator=(const StringFormat &source)
312    {
313        DllExports::GdipDeleteStringFormat(nativeFormat);
314        lastError = DllExports::GdipCloneStringFormat(
315            source.nativeFormat,
316            &nativeFormat
317        );
318        return *this;
319    }
320
321
322    // private constructor for copy
323    StringFormat(GpStringFormat * clonedStringFormat, Status status)
324    {
325        lastError = status;
326        nativeFormat = clonedStringFormat;
327
328    }
329
330    GpStringFormat *nativeFormat;
331    mutable Status  lastError;
332};
333
334// Generic constant string formats.
335
336static BYTE GenericTypographicStringFormatBuffer[sizeof(StringFormat)] = {0};
337static BYTE GenericDefaultStringFormatBuffer[sizeof(StringFormat)] = {0};
338
339static StringFormat *GenericTypographicStringFormat = NULL;
340static StringFormat *GenericDefaultStringFormat     = NULL;
341
342// Define the generic string formats
343
344
345inline const StringFormat *StringFormat::GenericDefault()
346{
347    if (GenericDefaultStringFormat != NULL)
348    {
349        return GenericDefaultStringFormat;
350    }
351
352    GenericDefaultStringFormat =
353        (StringFormat*)GenericDefaultStringFormatBuffer;
354
355    GenericDefaultStringFormat->lastError =
356        DllExports::GdipStringFormatGetGenericDefault(
357            &(GenericDefaultStringFormat->nativeFormat)
358        );
359
360    return GenericDefaultStringFormat;
361}
362
363inline const StringFormat *StringFormat::GenericTypographic()
364{
365    if (GenericTypographicStringFormat != NULL)
366    {
367        return GenericTypographicStringFormat;
368    }
369
370    GenericTypographicStringFormat =
371        (StringFormat*)GenericTypographicStringFormatBuffer;
372
373    GenericTypographicStringFormat->lastError =
374        DllExports::GdipStringFormatGetGenericTypographic(
375            &GenericTypographicStringFormat->nativeFormat
376        );
377
378    return GenericTypographicStringFormat;
379}
380
381#endif // !_GDIPLUSSTRINGFORMAT_H
382