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 (at) 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 */ 252