| 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): |
| 43 | 			nativeStringFormat(NULL), lastStatus(Ok) |
| 44 | 	{ |
| 45 | 		lastStatus = DllExports::GdipCreateStringFormat( |
| 46 | 				formatFlags, language, &nativeStringFormat); |
| 47 | 	} |
| 48 | 	StringFormat(const StringFormat *format): |
| 49 | 			nativeStringFormat(NULL), lastStatus(Ok) |
| 50 | 	{ |
| 51 | 		lastStatus = DllExports::GdipCloneStringFormat( |
| 52 | 				format ? format->nativeStringFormat : NULL, |
| 53 | 				&nativeStringFormat); |
| 54 | 	} |
| 55 | 	~StringFormat() |
| 56 | 	{ |
| 57 | 		DllExports::GdipDeleteStringFormat(nativeStringFormat); |
| 58 | 	} |
| 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 | |
| 77 | 	StringAlignment GetAlignment() const |
| 78 | 	{ |
| 79 | 		StringAlignment result = StringAlignmentNear; |
| 80 | 		updateStatus(DllExports::GdipGetStringFormatAlign( |
| 81 | 				nativeStringFormat, &result)); |
| 82 | 		return result; |
| 83 | 	} |
| 84 | 	LANGID GetDigitSubstitutionLanguage() const |
| 85 | 	{ |
| 86 | 		LANGID result = 0; |
| 87 | 		StringDigitSubstitute method; |
| 88 | 		updateStatus(DllExports::GdipGetStringFormatDigitSubstitution( |
| 89 | 				nativeStringFormat, &result, &method)); |
| 90 | 		return result; |
| 91 | 	} |
| 92 | 	StringDigitSubstitute GetDigitSubstitutionMethod() const |
| 93 | 	{ |
| 94 | 		LANGID language; |
| 95 | 		StringDigitSubstitute result = StringDigitSubstituteUser; |
| 96 | 		updateStatus(DllExports::GdipGetStringFormatDigitSubstitution( |
| 97 | 				nativeStringFormat, &language, &result)); |
| 98 | 		return result; |
| 99 | 	} |
| 100 | 	INT GetFormatFlags() const |
| 101 | 	{ |
| 102 | 		INT result = 0; |
| 103 | 		updateStatus(DllExports::GdipGetStringFormatFlags( |
| 104 | 				nativeStringFormat, &result)); |
| 105 | 		return result; |
| 106 | 	} |
| 107 | 	HotkeyPrefix GetHotkeyPrefix() const |
| 108 | 	{ |
| 109 | 		HotkeyPrefix result = HotkeyPrefixNone; |
| 110 | 		updateStatus(DllExports::GdipGetStringFormatHotkeyPrefix( |
| 111 | 				nativeStringFormat, (INT*) &result)); |
| 112 | 		return result; |
| 113 | 	} |
| 114 | 	Status GetLastStatus() const |
| 115 | 	{ |
| 116 | 		Status result = lastStatus; |
| 117 | 		lastStatus = Ok; |
| 118 | 		return result; |
| 119 | 	} |
| 120 | 	StringAlignment GetLineAlignment() const |
| 121 | 	{ |
| 122 | 		StringAlignment result = StringAlignmentNear; |
| 123 | 		updateStatus(DllExports::GdipGetStringFormatLineAlign( |
| 124 | 				nativeStringFormat, &result)); |
| 125 | 		return result; |
| 126 | 	} |
| 127 | 	INT GetMeasurableCharacterRangeCount() const |
| 128 | 	{ |
| 129 | 		INT result = 0; |
| 130 | 		updateStatus(DllExports::GdipGetStringFormatMeasurableCharacterRangeCount( |
| 131 | 				nativeStringFormat, &result)); |
| 132 | 		return result; |
| 133 | 	} |
| 134 | 	INT GetTabStopCount() const |
| 135 | 	{ |
| 136 | 		INT result = 0; |
| 137 | 		updateStatus(DllExports::GdipGetStringFormatTabStopCount( |
| 138 | 				nativeStringFormat, &result)); |
| 139 | 		return result; |
| 140 | 	} |
| 141 | 	Status GetTabStops(INT count, REAL *firstTabOffset, REAL *tabStops) |
| 142 | 	{ |
| 143 | 		return updateStatus(DllExports::GdipGetStringFormatTabStops( |
| 144 | 				nativeStringFormat, count, |
| 145 | 				firstTabOffset, tabStops)); |
| 146 | 	} |
| 147 | 	StringTrimming GetTrimming() const |
| 148 | 	{ |
| 149 | 		StringTrimming result = StringTrimmingNone; |
| 150 | 		updateStatus(DllExports::GdipGetStringFormatTrimming( |
| 151 | 				nativeStringFormat, &result)); |
| 152 | 		return result; |
| 153 | 	} |
| 154 | 	Status SetAlignment(StringAlignment align) |
| 155 | 	{ |
| 156 | 		return updateStatus(DllExports::GdipSetStringFormatAlign( |
| 157 | 				nativeStringFormat, align)); |
| 158 | 	} |
| 159 | 	Status SetDigitSubstitution(LANGID language, |
| 160 | 			StringDigitSubstitute substitute) |
| 161 | 	{ |
| 162 | 		return updateStatus(DllExports::GdipSetStringFormatDigitSubstitution( |
| 163 | 				nativeStringFormat, language, substitute)); |
| 164 | 	} |
| 165 | 	Status SetFormatFlags(INT flags) |
| 166 | 	{ |
| 167 | 		return updateStatus(DllExports::GdipSetStringFormatFlags( |
| 168 | 				nativeStringFormat, flags)); |
| 169 | 	} |
| 170 | 	Status SetHotkeyPrefix(HotkeyPrefix hotkeyPrefix) |
| 171 | 	{ |
| 172 | 		return updateStatus(DllExports::GdipSetStringFormatHotkeyPrefix( |
| 173 | 				nativeStringFormat, (INT) hotkeyPrefix)); |
| 174 | 	} |
| 175 | 	Status SetLineAlignment(StringAlignment align) |
| 176 | 	{ |
| 177 | 		return updateStatus(DllExports::GdipSetStringFormatLineAlign( |
| 178 | 				nativeStringFormat, align)); |
| 179 | 	} |
| 180 | 	Status SetMeasurableCharacterRanges(INT rangeCount, |
| 181 | 			const CharacterRange *ranges) |
| 182 | 	{ |
| 183 | 		return updateStatus(DllExports::GdipSetStringFormatMeasurableCharacterRanges( |
| 184 | 				nativeStringFormat, rangeCount, ranges)); |
| 185 | 	} |
| 186 | 	Status SetTabStops(REAL firstTabOffset, INT count, const REAL *tabStops) |
| 187 | 	{ |
| 188 | 		return updateStatus(DllExports::GdipSetStringFormatTabStops( |
| 189 | 				nativeStringFormat, firstTabOffset, |
| 190 | 				count, tabStops)); |
| 191 | 	} |
| 192 | 	Status SetTrimming(StringTrimming trimming) |
| 193 | 	{ |
| 194 | 		return updateStatus(DllExports::GdipSetStringFormatTrimming( |
| 195 | 				nativeStringFormat, trimming)); |
| 196 | 	} |
| 197 | |
| 198 | private: |
| 199 | 	StringFormat(GpStringFormat *stringFormat, Status status): |
| 200 | 		nativeStringFormat(stringFormat), lastStatus(status) {} |
| 201 | 	StringFormat(const StringFormat&); |
| 202 | 	StringFormat& operator=(const StringFormat&); |
| 203 | |
| 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 | |
| 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 | |
| 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 */ |