1 /*
2  * gdiplusstringformat.h
3  *
4  * GDI+ StringFormat class
5  *
6  * This file is part of the w32api package.
7  *
8  * Contributors:
9  *   Created by Markus Koenig <markus@stber-koenig.de>
10  *
11  * THIS SOFTWARE IS NOT COPYRIGHTED
12  *
13  * This source code is offered for use in the public domain. You may
14  * use, modify or distribute it freely.
15  *
16  * This code is distributed in the hope that it will be useful but
17  * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
18  * DISCLAIMED. This includes but is not limited to warranties of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  */
22 
23 #ifndef __GDIPLUS_STRINGFORMAT_H
24 #define __GDIPLUS_STRINGFORMAT_H
25 #if __GNUC__ >=3
26 #pragma GCC system_header
27 #endif
28 
29 #ifndef __cplusplus
30 #error "A C++ compiler is required to include gdiplusstringformat.h."
31 #endif
32 
33 class StringFormat: public GdiplusBase
34 {
35 	friend class Graphics;
36 	friend class GraphicsPath;
37 
38 public:
39 	static const StringFormat* GenericDefault();
40 	static const StringFormat* GenericTypographic();
41 
42 	StringFormat(INT formatFlags = 0, LANGID language = LANG_NEUTRAL):
nativeStringFormat(NULL)43 			nativeStringFormat(NULL), lastStatus(Ok)
44 	{
45 		lastStatus = DllExports::GdipCreateStringFormat(
46 				formatFlags, language, &nativeStringFormat);
47 	}
StringFormat(const StringFormat * format)48 	StringFormat(const StringFormat *format):
49 			nativeStringFormat(NULL), lastStatus(Ok)
50 	{
51 		lastStatus = DllExports::GdipCloneStringFormat(
52 				format ? format->nativeStringFormat : NULL,
53 				&nativeStringFormat);
54 	}
~StringFormat()55 	~StringFormat()
56 	{
57 		DllExports::GdipDeleteStringFormat(nativeStringFormat);
58 	}
Clone()59 	StringFormat* Clone() const
60 	{
61 		GpStringFormat *cloneStringFormat = NULL;
62 		Status status = updateStatus(DllExports::GdipCloneStringFormat(
63 				nativeStringFormat, &cloneStringFormat));
64 		if (status == Ok) {
65 			StringFormat *result = new StringFormat(
66 					cloneStringFormat, lastStatus);
67 			if (!result) {
68 				DllExports::GdipDeleteStringFormat(cloneStringFormat);
69 				lastStatus = OutOfMemory;
70 			}
71 			return result;
72 		} else {
73 			return NULL;
74 		}
75 	}
76 
GetAlignment()77 	StringAlignment GetAlignment() const
78 	{
79 		StringAlignment result = StringAlignmentNear;
80 		updateStatus(DllExports::GdipGetStringFormatAlign(
81 				nativeStringFormat, &result));
82 		return result;
83 	}
GetDigitSubstitutionLanguage()84 	LANGID GetDigitSubstitutionLanguage() const
85 	{
86 		LANGID result = 0;
87 		StringDigitSubstitute method;
88 		updateStatus(DllExports::GdipGetStringFormatDigitSubstitution(
89 				nativeStringFormat, &result, &method));
90 		return result;
91 	}
GetDigitSubstitutionMethod()92 	StringDigitSubstitute GetDigitSubstitutionMethod() const
93 	{
94 		LANGID language;
95 		StringDigitSubstitute result = StringDigitSubstituteUser;
96 		updateStatus(DllExports::GdipGetStringFormatDigitSubstitution(
97 				nativeStringFormat, &language, &result));
98 		return result;
99 	}
GetFormatFlags()100 	INT GetFormatFlags() const
101 	{
102 		INT result = 0;
103 		updateStatus(DllExports::GdipGetStringFormatFlags(
104 				nativeStringFormat, &result));
105 		return result;
106 	}
GetHotkeyPrefix()107 	HotkeyPrefix GetHotkeyPrefix() const
108 	{
109 		HotkeyPrefix result = HotkeyPrefixNone;
110 		updateStatus(DllExports::GdipGetStringFormatHotkeyPrefix(
111 				nativeStringFormat, (INT*) &result));
112 		return result;
113 	}
GetLastStatus()114 	Status GetLastStatus() const
115 	{
116 		Status result = lastStatus;
117 		lastStatus = Ok;
118 		return result;
119 	}
GetLineAlignment()120 	StringAlignment GetLineAlignment() const
121 	{
122 		StringAlignment result = StringAlignmentNear;
123 		updateStatus(DllExports::GdipGetStringFormatLineAlign(
124 				nativeStringFormat, &result));
125 		return result;
126 	}
GetMeasurableCharacterRangeCount()127 	INT GetMeasurableCharacterRangeCount() const
128 	{
129 		INT result = 0;
130 		updateStatus(DllExports::GdipGetStringFormatMeasurableCharacterRangeCount(
131 				nativeStringFormat, &result));
132 		return result;
133 	}
GetTabStopCount()134 	INT GetTabStopCount() const
135 	{
136 		INT result = 0;
137 		updateStatus(DllExports::GdipGetStringFormatTabStopCount(
138 				nativeStringFormat, &result));
139 		return result;
140 	}
GetTabStops(INT count,REAL * firstTabOffset,REAL * tabStops)141 	Status GetTabStops(INT count, REAL *firstTabOffset, REAL *tabStops)
142 	{
143 		return updateStatus(DllExports::GdipGetStringFormatTabStops(
144 				nativeStringFormat, count,
145 				firstTabOffset, tabStops));
146 	}
GetTrimming()147 	StringTrimming GetTrimming() const
148 	{
149 		StringTrimming result = StringTrimmingNone;
150 		updateStatus(DllExports::GdipGetStringFormatTrimming(
151 				nativeStringFormat, &result));
152 		return result;
153 	}
SetAlignment(StringAlignment align)154 	Status SetAlignment(StringAlignment align)
155 	{
156 		return updateStatus(DllExports::GdipSetStringFormatAlign(
157 				nativeStringFormat, align));
158 	}
SetDigitSubstitution(LANGID language,StringDigitSubstitute substitute)159 	Status SetDigitSubstitution(LANGID language,
160 			StringDigitSubstitute substitute)
161 	{
162 		return updateStatus(DllExports::GdipSetStringFormatDigitSubstitution(
163 				nativeStringFormat, language, substitute));
164 	}
SetFormatFlags(INT flags)165 	Status SetFormatFlags(INT flags)
166 	{
167 		return updateStatus(DllExports::GdipSetStringFormatFlags(
168 				nativeStringFormat, flags));
169 	}
SetHotkeyPrefix(HotkeyPrefix hotkeyPrefix)170 	Status SetHotkeyPrefix(HotkeyPrefix hotkeyPrefix)
171 	{
172 		return updateStatus(DllExports::GdipSetStringFormatHotkeyPrefix(
173 				nativeStringFormat, (INT) hotkeyPrefix));
174 	}
SetLineAlignment(StringAlignment align)175 	Status SetLineAlignment(StringAlignment align)
176 	{
177 		return updateStatus(DllExports::GdipSetStringFormatLineAlign(
178 				nativeStringFormat, align));
179 	}
SetMeasurableCharacterRanges(INT rangeCount,const CharacterRange * ranges)180 	Status SetMeasurableCharacterRanges(INT rangeCount,
181 			const CharacterRange *ranges)
182 	{
183 		return updateStatus(DllExports::GdipSetStringFormatMeasurableCharacterRanges(
184 				nativeStringFormat, rangeCount, ranges));
185 	}
SetTabStops(REAL firstTabOffset,INT count,const REAL * tabStops)186 	Status SetTabStops(REAL firstTabOffset, INT count, const REAL *tabStops)
187 	{
188 		return updateStatus(DllExports::GdipSetStringFormatTabStops(
189 				nativeStringFormat, firstTabOffset,
190 				count, tabStops));
191 	}
SetTrimming(StringTrimming trimming)192 	Status SetTrimming(StringTrimming trimming)
193 	{
194 		return updateStatus(DllExports::GdipSetStringFormatTrimming(
195 				nativeStringFormat, trimming));
196 	}
197 
198 private:
StringFormat(GpStringFormat * stringFormat,Status status)199 	StringFormat(GpStringFormat *stringFormat, Status status):
200 		nativeStringFormat(stringFormat), lastStatus(status) {}
201 	StringFormat(const StringFormat&);
202 	StringFormat& operator=(const StringFormat&);
203 
updateStatus(Status newStatus)204 	Status updateStatus(Status newStatus) const
205 	{
206 		if (newStatus != Ok) lastStatus = newStatus;
207 		return newStatus;
208 	}
209 
210 	GpStringFormat *nativeStringFormat;
211 	mutable Status lastStatus;
212 };
213 
214 
215 // FIXME: do StringFormat::GenericDefault() et al. need to be thread safe?
216 // FIXME: maybe put this in gdiplus.c?
217 
218 extern "C" void *_GdipStringFormatCachedGenericDefault;
219 extern "C" void *_GdipStringFormatCachedGenericTypographic;
220 
GenericDefault()221 __inline__ const StringFormat* StringFormat::GenericDefault()
222 {
223 	if (!_GdipStringFormatCachedGenericDefault) {
224 		GpStringFormat *nativeStringFormat = 0;
225 		Status status = DllExports::GdipStringFormatGetGenericDefault(
226 				&nativeStringFormat);
227 		if (status == Ok && nativeStringFormat) {
228 			_GdipStringFormatCachedGenericDefault = (void*)
229 				new StringFormat(nativeStringFormat, Ok);
230 		}
231 	}
232 	return (StringFormat*) _GdipStringFormatCachedGenericDefault;
233 }
234 
GenericTypographic()235 __inline__ const StringFormat* StringFormat::GenericTypographic()
236 {
237 	if (!_GdipStringFormatCachedGenericTypographic) {
238 		GpStringFormat *nativeStringFormat = 0;
239 		Status status = DllExports::GdipStringFormatGetGenericTypographic(
240 				&nativeStringFormat);
241 		if (status == Ok && nativeStringFormat) {
242 			_GdipStringFormatCachedGenericTypographic = (void*)
243 				new StringFormat(nativeStringFormat, Ok);
244 		}
245 	}
246 	return (StringFormat*) _GdipStringFormatCachedGenericTypographic;
247 }
248 
249 
250 
251 #endif /* __GDIPLUS_STRINGFORMAT_H */
252