Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "unotools/fontcfg.hxx"
22 :
23 : #include "tools/stream.hxx"
24 : #include "tools/vcompat.hxx"
25 : #include "tools/debug.hxx"
26 : #include <tools/gen.hxx>
27 :
28 : #include "vcl/font.hxx"
29 :
30 : #include "impfont.hxx"
31 : #include "outfont.hxx"
32 : #include "sft.hxx"
33 :
34 : #include <sal/macros.h>
35 :
36 : #include <algorithm>
37 :
38 : using namespace vcl;
39 :
40 : DBG_NAME( Font )
41 :
42 29904 : Impl_Font::Impl_Font() :
43 : maColor( COL_TRANSPARENT ),
44 29904 : maFillColor( COL_TRANSPARENT )
45 : {
46 29904 : mnRefCount = 1;
47 29904 : meCharSet = RTL_TEXTENCODING_DONTKNOW;
48 29904 : meLanguage = LANGUAGE_DONTKNOW;
49 29904 : meCJKLanguage = LANGUAGE_DONTKNOW;
50 29904 : meFamily = FAMILY_DONTKNOW;
51 29904 : mePitch = PITCH_DONTKNOW;
52 29904 : meAlign = ALIGN_TOP;
53 29904 : meWeight = WEIGHT_DONTKNOW;
54 29904 : meWidthType = WIDTH_DONTKNOW;
55 29904 : meItalic = ITALIC_NONE;
56 29904 : meUnderline = UNDERLINE_NONE;
57 29904 : meOverline = UNDERLINE_NONE;
58 29904 : meStrikeout = STRIKEOUT_NONE;
59 29904 : meRelief = RELIEF_NONE;
60 29904 : meEmphasisMark = EMPHASISMARK_NONE;
61 29904 : mnOrientation = 0;
62 29904 : mnKerning = 0;
63 29904 : mbWordLine = false;
64 29904 : mbOutline = false;
65 29904 : mbShadow = false;
66 29904 : mbVertical = false;
67 29904 : mbTransparent = true;
68 29904 : mbConfigLookup = false;
69 29904 : }
70 :
71 2705097 : Impl_Font::Impl_Font( const Impl_Font& rImplFont )
72 : : maFamilyName( rImplFont.maFamilyName ),
73 : maStyleName( rImplFont.maStyleName ),
74 : maSize( rImplFont.maSize ),
75 : maColor( rImplFont.maColor ),
76 2705097 : maFillColor( rImplFont.maFillColor )
77 : {
78 2705097 : mnRefCount = 1;
79 2705097 : meCharSet = rImplFont.meCharSet;
80 2705097 : meLanguage = rImplFont.meLanguage;
81 2705097 : meCJKLanguage = rImplFont.meCJKLanguage;
82 2705097 : meFamily = rImplFont.meFamily;
83 2705097 : mePitch = rImplFont.mePitch;
84 2705097 : meAlign = rImplFont.meAlign;
85 2705097 : meWeight = rImplFont.meWeight;
86 2705097 : meWidthType = rImplFont.meWidthType;
87 2705097 : meItalic = rImplFont.meItalic;
88 2705097 : meUnderline = rImplFont.meUnderline;
89 2705097 : meOverline = rImplFont.meOverline;
90 2705097 : meStrikeout = rImplFont.meStrikeout;
91 2705097 : meRelief = rImplFont.meRelief;
92 2705097 : meEmphasisMark = rImplFont.meEmphasisMark;
93 2705097 : mnOrientation = rImplFont.mnOrientation;
94 2705097 : mnKerning = rImplFont.mnKerning;
95 2705097 : mbWordLine = rImplFont.mbWordLine;
96 2705097 : mbOutline = rImplFont.mbOutline;
97 2705097 : mbShadow = rImplFont.mbShadow;
98 2705097 : mbVertical = rImplFont.mbVertical;
99 2705097 : mbTransparent = rImplFont.mbTransparent;
100 2705097 : mbConfigLookup = rImplFont.mbConfigLookup;
101 2705097 : }
102 :
103 864017 : bool Impl_Font::operator==( const Impl_Font& rOther ) const
104 : {
105 : // equality tests split up for easier debugging
106 864017 : if( (meWeight != rOther.meWeight)
107 828746 : || (meItalic != rOther.meItalic)
108 825984 : || (meFamily != rOther.meFamily)
109 766628 : || (mePitch != rOther.mePitch) )
110 97623 : return false;
111 :
112 766394 : if( (meCharSet != rOther.meCharSet)
113 675557 : || (meLanguage != rOther.meLanguage)
114 673742 : || (meCJKLanguage != rOther.meCJKLanguage)
115 673602 : || (meAlign != rOther.meAlign) )
116 92795 : return false;
117 :
118 1347198 : if( (maSize != rOther.maSize)
119 652503 : || (mnOrientation != rOther.mnOrientation)
120 1325951 : || (mbVertical != rOther.mbVertical) )
121 21247 : return false;
122 :
123 1304704 : if( (maFamilyName != rOther.maFamilyName)
124 652352 : || (maStyleName != rOther.maStyleName) )
125 429 : return false;
126 :
127 1303846 : if( (maColor != rOther.maColor)
128 651923 : || (maFillColor != rOther.maFillColor) )
129 477 : return false;
130 :
131 651446 : if( (meUnderline != rOther.meUnderline)
132 651106 : || (meOverline != rOther.meOverline)
133 651086 : || (meStrikeout != rOther.meStrikeout)
134 650729 : || (meRelief != rOther.meRelief)
135 650011 : || (meEmphasisMark != rOther.meEmphasisMark)
136 649614 : || (mbWordLine != rOther.mbWordLine)
137 649505 : || (mbOutline != rOther.mbOutline)
138 649345 : || (mbShadow != rOther.mbShadow)
139 649325 : || (mnKerning != rOther.mnKerning)
140 648725 : || (mbTransparent != rOther.mbTransparent) )
141 2721 : return false;
142 :
143 648725 : return true;
144 : }
145 :
146 22135 : void Impl_Font::AskConfig()
147 : {
148 22135 : if( mbConfigLookup )
149 34158 : return;
150 :
151 10112 : mbConfigLookup = true;
152 :
153 : // prepare the FontSubst configuration lookup
154 10112 : const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
155 :
156 10112 : OUString aShortName;
157 20224 : OUString aFamilyName;
158 10112 : sal_uLong nType = 0;
159 10112 : FontWeight eWeight = WEIGHT_DONTKNOW;
160 10112 : FontWidth eWidthType = WIDTH_DONTKNOW;
161 20224 : OUString aMapName = maFamilyName;
162 10112 : GetEnglishSearchFontName( aMapName );
163 : utl::FontSubstConfiguration::getMapName( aMapName,
164 10112 : aShortName, aFamilyName, eWeight, eWidthType, nType );
165 :
166 : // lookup the font name in the configuration
167 10112 : const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
168 :
169 : // if the direct lookup failed try again with an alias name
170 10112 : if ( !pFontAttr && (aShortName != aMapName) )
171 412 : pFontAttr = rFontSubst.getSubstInfo( aShortName );
172 :
173 10112 : if( pFontAttr )
174 : {
175 : // the font was found in the configuration
176 6046 : if( meFamily == FAMILY_DONTKNOW )
177 : {
178 4867 : if ( pFontAttr->Type & IMPL_FONT_ATTR_SERIF )
179 1993 : meFamily = FAMILY_ROMAN;
180 2874 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_SANSSERIF )
181 575 : meFamily = FAMILY_SWISS;
182 2299 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_TYPEWRITER )
183 10 : meFamily = FAMILY_MODERN;
184 2289 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_ITALIC )
185 0 : meFamily = FAMILY_SCRIPT;
186 2289 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_DECORATIVE )
187 0 : meFamily = FAMILY_DECORATIVE;
188 : }
189 :
190 6046 : if( mePitch == PITCH_DONTKNOW )
191 : {
192 5105 : if ( pFontAttr->Type & IMPL_FONT_ATTR_FIXED )
193 10 : mePitch = PITCH_FIXED;
194 : }
195 : }
196 :
197 : // if some attributes are still unknown then use the FontSubst magic
198 10112 : if( meFamily == FAMILY_DONTKNOW )
199 : {
200 6095 : if( nType & IMPL_FONT_ATTR_SERIF )
201 5 : meFamily = FAMILY_ROMAN;
202 6090 : else if( nType & IMPL_FONT_ATTR_SANSSERIF )
203 2 : meFamily = FAMILY_SWISS;
204 6088 : else if( nType & IMPL_FONT_ATTR_TYPEWRITER )
205 0 : meFamily = FAMILY_MODERN;
206 6088 : else if( nType & IMPL_FONT_ATTR_ITALIC )
207 0 : meFamily = FAMILY_SCRIPT;
208 6088 : else if( nType & IMPL_FONT_ATTR_DECORATIVE )
209 0 : meFamily = FAMILY_DECORATIVE;
210 : }
211 :
212 10112 : if( meWeight == WEIGHT_DONTKNOW )
213 8715 : meWeight = eWeight;
214 10112 : if( meWidthType == WIDTH_DONTKNOW )
215 19754 : meWidthType = eWidthType;
216 : }
217 :
218 9737176 : void Font::MakeUnique()
219 : {
220 : // create a copy if others still reference it
221 9737176 : if ( mpImplFont->mnRefCount != 1 )
222 : {
223 2705097 : if ( mpImplFont->mnRefCount )
224 2189521 : mpImplFont->mnRefCount--;
225 2705097 : mpImplFont = new Impl_Font( *mpImplFont );
226 : }
227 9737176 : }
228 :
229 2416722 : Font::Font()
230 : {
231 : DBG_CTOR( Font, NULL );
232 :
233 2416722 : static Impl_Font aStaticImplFont;
234 : // RefCount is zero for static objects
235 2416722 : aStaticImplFont.mnRefCount = 0;
236 2416722 : mpImplFont = &aStaticImplFont;
237 2416722 : }
238 :
239 3822897 : Font::Font( const Font& rFont )
240 : {
241 : DBG_CTOR( Font, NULL );
242 : DBG_CHKOBJ( &rFont, Font, NULL );
243 3822897 : bool bRefIncrementable = rFont.mpImplFont->mnRefCount < ::std::numeric_limits<FontRefCount>::max();
244 : DBG_ASSERT( bRefIncrementable, "Font: RefCount overflow" );
245 :
246 3822897 : mpImplFont = rFont.mpImplFont;
247 : // do not count static objects (where RefCount is zero)
248 3822897 : if ( mpImplFont->mnRefCount && bRefIncrementable )
249 3797407 : mpImplFont->mnRefCount++;
250 3822897 : }
251 :
252 9790 : Font::Font( const String& rFamilyName, const Size& rSize )
253 : {
254 : DBG_CTOR( Font, NULL );
255 :
256 9790 : mpImplFont = new Impl_Font;
257 9790 : mpImplFont->maFamilyName = rFamilyName;
258 9790 : mpImplFont->maSize = rSize;
259 9790 : }
260 :
261 19743 : Font::Font( const String& rFamilyName, const String& rStyleName, const Size& rSize )
262 : {
263 : DBG_CTOR( Font, NULL );
264 :
265 19743 : mpImplFont = new Impl_Font;
266 19743 : mpImplFont->maFamilyName= rFamilyName;
267 19743 : mpImplFont->maStyleName = rStyleName;
268 19743 : mpImplFont->maSize = rSize;
269 19743 : }
270 :
271 227 : Font::Font( FontFamily eFamily, const Size& rSize )
272 : {
273 : DBG_CTOR( Font, NULL );
274 :
275 227 : mpImplFont = new Impl_Font;
276 227 : mpImplFont->meFamily = eFamily;
277 227 : mpImplFont->maSize = rSize;
278 227 : }
279 :
280 6263257 : Font::~Font()
281 : {
282 : DBG_DTOR( Font, NULL );
283 :
284 : // decrement reference counter and delete if last reference
285 : // if the object is not static (Refcounter==0)
286 6263257 : if ( mpImplFont->mnRefCount )
287 : {
288 6151077 : if ( mpImplFont->mnRefCount == 1 )
289 1751535 : delete mpImplFont;
290 : else
291 4399542 : mpImplFont->mnRefCount--;
292 : }
293 6263257 : }
294 :
295 1092088 : void Font::SetColor( const Color& rColor )
296 : {
297 : DBG_CHKTHIS( Font, NULL );
298 :
299 1092088 : if( mpImplFont->maColor != rColor )
300 : {
301 304603 : MakeUnique();
302 304603 : mpImplFont->maColor = rColor;
303 : }
304 1092088 : }
305 :
306 10078 : void Font::SetFillColor( const Color& rColor )
307 : {
308 : DBG_CHKTHIS( Font, NULL );
309 :
310 10078 : MakeUnique();
311 10078 : mpImplFont->maFillColor = rColor;
312 10078 : if ( rColor.GetTransparency() )
313 2166 : mpImplFont->mbTransparent = true;
314 10078 : }
315 :
316 1088295 : void Font::SetTransparent( sal_Bool bTransparent )
317 : {
318 : DBG_CHKTHIS( Font, NULL );
319 :
320 1088295 : if( mpImplFont->mbTransparent != bTransparent )
321 : {
322 7361 : MakeUnique();
323 7361 : mpImplFont->mbTransparent = bTransparent;
324 : }
325 1088295 : }
326 :
327 1113180 : void Font::SetAlign( FontAlign eAlign )
328 : {
329 : DBG_CHKTHIS( Font, NULL );
330 :
331 1113180 : if( mpImplFont->meAlign != eAlign )
332 : {
333 88792 : MakeUnique();
334 88792 : mpImplFont->meAlign = eAlign;
335 : }
336 1113180 : }
337 :
338 2069961 : void Font::SetName( const OUString& rFamilyName )
339 : {
340 : DBG_CHKTHIS( Font, NULL );
341 :
342 2069961 : MakeUnique();
343 2069961 : mpImplFont->maFamilyName = rFamilyName;
344 2069961 : }
345 :
346 959193 : void Font::SetStyleName( const String& rStyleName )
347 : {
348 : DBG_CHKTHIS( Font, NULL );
349 :
350 959193 : MakeUnique();
351 959193 : mpImplFont->maStyleName = rStyleName;
352 959193 : }
353 :
354 1834393 : void Font::SetSize( const Size& rSize )
355 : {
356 : DBG_CHKTHIS( Font, NULL );
357 :
358 1834393 : if( mpImplFont->maSize != rSize )
359 : {
360 1083281 : MakeUnique();
361 1083281 : mpImplFont->maSize = rSize;
362 : }
363 1834393 : }
364 :
365 2016190 : void Font::SetFamily( FontFamily eFamily )
366 : {
367 : DBG_CHKTHIS( Font, NULL );
368 :
369 2016190 : if( mpImplFont->meFamily != eFamily )
370 : {
371 850837 : MakeUnique();
372 850837 : mpImplFont->meFamily = eFamily;
373 : }
374 2016190 : }
375 :
376 2037133 : void Font::SetCharSet( CharSet eCharSet )
377 : {
378 : DBG_CHKTHIS( Font, NULL );
379 :
380 2037133 : if( mpImplFont->meCharSet != eCharSet )
381 : {
382 1140309 : MakeUnique();
383 1140309 : mpImplFont->meCharSet = eCharSet;
384 : }
385 2037133 : }
386 :
387 2043130 : void Font::SetLanguage( LanguageType eLanguage )
388 : {
389 : DBG_CHKTHIS( Font, NULL );
390 :
391 2043130 : if( mpImplFont->meLanguage != eLanguage )
392 : {
393 139302 : MakeUnique();
394 139302 : mpImplFont->meLanguage = eLanguage;
395 : }
396 2043130 : }
397 :
398 738121 : void Font::SetCJKContextLanguage( LanguageType eLanguage )
399 : {
400 : DBG_CHKTHIS( Font, NULL );
401 :
402 738121 : if( mpImplFont->meCJKLanguage != eLanguage )
403 : {
404 654000 : MakeUnique();
405 654000 : mpImplFont->meCJKLanguage = eLanguage;
406 : }
407 738121 : }
408 :
409 2035600 : void Font::SetPitch( FontPitch ePitch )
410 : {
411 : DBG_CHKTHIS( Font, NULL );
412 :
413 2035600 : if( mpImplFont->mePitch != ePitch )
414 : {
415 547873 : MakeUnique();
416 547873 : mpImplFont->mePitch = ePitch;
417 : }
418 2035600 : }
419 :
420 804798 : void Font::SetOrientation( short nOrientation )
421 : {
422 : DBG_CHKTHIS( Font, NULL );
423 :
424 804798 : if( mpImplFont->mnOrientation != nOrientation )
425 : {
426 9091 : MakeUnique();
427 9091 : mpImplFont->mnOrientation = nOrientation;
428 : }
429 804798 : }
430 :
431 264933 : void Font::SetVertical( sal_Bool bVertical )
432 : {
433 : DBG_CHKTHIS( Font, NULL );
434 :
435 264933 : if( mpImplFont->mbVertical != bVertical )
436 : {
437 6 : MakeUnique();
438 6 : mpImplFont->mbVertical = bVertical;
439 : }
440 264933 : }
441 :
442 869161 : void Font::SetKerning( FontKerning nKerning )
443 : {
444 : DBG_CHKTHIS( Font, NULL );
445 :
446 869161 : if( mpImplFont->mnKerning != nKerning )
447 : {
448 36699 : MakeUnique();
449 36699 : mpImplFont->mnKerning = nKerning;
450 : }
451 869161 : }
452 :
453 4269 : sal_Bool Font::IsKerning() const
454 : {
455 4269 : return (mpImplFont->mnKerning & KERNING_FONTSPECIFIC) != 0;
456 : }
457 :
458 2016092 : void Font::SetWeight( FontWeight eWeight )
459 : {
460 : DBG_CHKTHIS( Font, NULL );
461 :
462 2016092 : if( mpImplFont->meWeight != eWeight )
463 : {
464 680783 : MakeUnique();
465 680783 : mpImplFont->meWeight = eWeight;
466 : }
467 2016092 : }
468 :
469 926087 : void Font::SetWidthType( FontWidth eWidth )
470 : {
471 : DBG_CHKTHIS( Font, NULL );
472 :
473 926087 : if( mpImplFont->meWidthType != eWidth )
474 : {
475 816051 : MakeUnique();
476 816051 : mpImplFont->meWidthType = eWidth;
477 : }
478 926087 : }
479 :
480 1824552 : void Font::SetItalic( FontItalic eItalic )
481 : {
482 : DBG_CHKTHIS( Font, NULL );
483 :
484 1824552 : if( mpImplFont->meItalic != eItalic )
485 : {
486 157738 : MakeUnique();
487 157738 : mpImplFont->meItalic = eItalic;
488 : }
489 1824552 : }
490 :
491 881088 : void Font::SetOutline( sal_Bool bOutline )
492 : {
493 : DBG_CHKTHIS( Font, NULL );
494 :
495 881088 : if( mpImplFont->mbOutline != bOutline )
496 : {
497 14037 : MakeUnique();
498 14037 : mpImplFont->mbOutline = bOutline;
499 : }
500 881088 : }
501 :
502 863120 : void Font::SetShadow( sal_Bool bShadow )
503 : {
504 : DBG_CHKTHIS( Font, NULL );
505 :
506 863120 : if( mpImplFont->mbShadow != bShadow )
507 : {
508 13646 : MakeUnique();
509 13646 : mpImplFont->mbShadow = bShadow;
510 : }
511 863120 : }
512 :
513 871653 : void Font::SetUnderline( FontUnderline eUnderline )
514 : {
515 : DBG_CHKTHIS( Font, NULL );
516 :
517 871653 : if( mpImplFont->meUnderline != eUnderline )
518 : {
519 31513 : MakeUnique();
520 31513 : mpImplFont->meUnderline = eUnderline;
521 : }
522 871653 : }
523 :
524 858806 : void Font::SetOverline( FontUnderline eOverline )
525 : {
526 : DBG_CHKTHIS( Font, NULL );
527 :
528 858806 : if( mpImplFont->meOverline != eOverline )
529 : {
530 12008 : MakeUnique();
531 12008 : mpImplFont->meOverline = eOverline;
532 : }
533 858806 : }
534 :
535 866353 : void Font::SetStrikeout( FontStrikeout eStrikeout )
536 : {
537 : DBG_CHKTHIS( Font, NULL );
538 :
539 866353 : if( mpImplFont->meStrikeout != eStrikeout )
540 : {
541 21949 : MakeUnique();
542 21949 : mpImplFont->meStrikeout = eStrikeout;
543 : }
544 866353 : }
545 :
546 840877 : void Font::SetRelief( FontRelief eRelief )
547 : {
548 : DBG_CHKTHIS( Font, NULL );
549 :
550 840877 : if( mpImplFont->meRelief != eRelief )
551 : {
552 22018 : MakeUnique();
553 22018 : mpImplFont->meRelief = eRelief;
554 : }
555 840877 : }
556 :
557 863098 : void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark )
558 : {
559 : DBG_CHKTHIS( Font, NULL );
560 :
561 863098 : if( mpImplFont->meEmphasisMark != eEmphasisMark )
562 : {
563 23089 : MakeUnique();
564 23089 : mpImplFont->meEmphasisMark = eEmphasisMark;
565 : }
566 863098 : }
567 :
568 873048 : void Font::SetWordLineMode( sal_Bool bWordLine )
569 : {
570 : DBG_CHKTHIS( Font, NULL );
571 :
572 873048 : if( mpImplFont->mbWordLine != bWordLine )
573 : {
574 17191 : MakeUnique();
575 17191 : mpImplFont->mbWordLine = bWordLine;
576 : }
577 873048 : }
578 :
579 3994685 : Font& Font::operator=( const Font& rFont )
580 : {
581 : DBG_CHKTHIS( Font, NULL );
582 : DBG_CHKOBJ( &rFont, Font, NULL );
583 3994685 : bool bRefIncrementable = rFont.mpImplFont->mnRefCount < ::std::numeric_limits<FontRefCount>::max();
584 : DBG_ASSERT( bRefIncrementable, "Font: RefCount overflow" );
585 :
586 : // Increment RefCount first, so that we can reference ourselves
587 : // RefCount == 0 for static objects
588 3994685 : if ( rFont.mpImplFont->mnRefCount && bRefIncrementable )
589 3990786 : rFont.mpImplFont->mnRefCount++;
590 :
591 : // If it's not static ImplData and if it's the last reference, delete it
592 : // else decrement RefCount
593 3994685 : if ( mpImplFont->mnRefCount )
594 : {
595 2176748 : if ( mpImplFont->mnRefCount == 1 )
596 979094 : delete mpImplFont;
597 : else
598 1197654 : mpImplFont->mnRefCount--;
599 : }
600 :
601 3994685 : mpImplFont = rFont.mpImplFont;
602 :
603 3994685 : return *this;
604 : }
605 :
606 1355751 : sal_Bool Font::operator==( const Font& rFont ) const
607 : {
608 : DBG_CHKTHIS( Font, NULL );
609 : DBG_CHKOBJ( &rFont, Font, NULL );
610 :
611 1355751 : if( mpImplFont == rFont.mpImplFont )
612 491734 : return sal_True;
613 864017 : if( *mpImplFont == *rFont.mpImplFont )
614 648725 : return sal_True;
615 :
616 215292 : return sal_False;
617 : }
618 :
619 3873 : void Font::Merge( const Font& rFont )
620 : {
621 3873 : if ( rFont.GetName().Len() )
622 : {
623 3845 : SetName( rFont.GetName() );
624 3845 : SetStyleName( rFont.GetStyleName() );
625 3845 : SetCharSet( GetCharSet() );
626 3845 : SetLanguage( rFont.GetLanguage() );
627 3845 : SetCJKContextLanguage( rFont.GetCJKContextLanguage() );
628 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
629 3845 : SetFamily( rFont.mpImplFont->meFamily );
630 3845 : SetPitch( rFont.mpImplFont->mePitch );
631 : }
632 :
633 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
634 3873 : if ( rFont.mpImplFont->meWeight != WEIGHT_DONTKNOW )
635 3853 : SetWeight( rFont.GetWeight() );
636 3873 : if ( rFont.mpImplFont->meItalic != ITALIC_DONTKNOW )
637 3873 : SetItalic( rFont.GetItalic() );
638 3873 : if ( rFont.mpImplFont->meWidthType != WIDTH_DONTKNOW )
639 3745 : SetWidthType( rFont.GetWidthType() );
640 :
641 :
642 3873 : if ( rFont.GetSize().Height() )
643 3853 : SetSize( rFont.GetSize() );
644 3873 : if ( rFont.GetUnderline() != UNDERLINE_DONTKNOW )
645 : {
646 3873 : SetUnderline( rFont.GetUnderline() );
647 3873 : SetWordLineMode( rFont.IsWordLineMode() );
648 : }
649 3873 : if ( rFont.GetOverline() != UNDERLINE_DONTKNOW )
650 : {
651 3873 : SetOverline( rFont.GetOverline() );
652 3873 : SetWordLineMode( rFont.IsWordLineMode() );
653 : }
654 3873 : if ( rFont.GetStrikeout() != STRIKEOUT_DONTKNOW )
655 : {
656 3873 : SetStrikeout( rFont.GetStrikeout() );
657 3873 : SetWordLineMode( rFont.IsWordLineMode() );
658 : }
659 :
660 : // Defaults?
661 3873 : SetOrientation( rFont.GetOrientation() );
662 3873 : SetVertical( rFont.IsVertical() );
663 3873 : SetEmphasisMark( rFont.GetEmphasisMark() );
664 3873 : SetKerning( rFont.IsKerning() );
665 3873 : SetOutline( rFont.IsOutline() );
666 3873 : SetShadow( rFont.IsShadow() );
667 3873 : SetRelief( rFont.GetRelief() );
668 3873 : }
669 :
670 802155 : void Font::GetFontAttributes( ImplFontAttributes& rAttrs ) const
671 : {
672 802155 : rAttrs.SetFamilyName( mpImplFont->maFamilyName );
673 802155 : rAttrs.SetStyleName( mpImplFont->maStyleName );
674 802155 : rAttrs.SetFamilyType( mpImplFont->meFamily );
675 802155 : rAttrs.SetPitch( mpImplFont->mePitch );
676 802155 : rAttrs.SetItalic( mpImplFont->meItalic );
677 802155 : rAttrs.SetWeight( mpImplFont->meWeight );
678 802155 : rAttrs.SetWidthType( WIDTH_DONTKNOW );
679 802155 : rAttrs.SetSymbolFlag( mpImplFont->meCharSet == RTL_TEXTENCODING_SYMBOL );
680 802155 : }
681 :
682 25767 : SvStream& operator>>( SvStream& rIStm, Impl_Font& rImpl_Font )
683 : {
684 25767 : VersionCompat aCompat( rIStm, STREAM_READ );
685 : sal_uInt16 nTmp16;
686 : sal_Bool bTmp;
687 : sal_uInt8 nTmp8;
688 :
689 25767 : rImpl_Font.maFamilyName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
690 25767 : rImpl_Font.maStyleName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
691 25767 : rIStm >> rImpl_Font.maSize;
692 :
693 25767 : rIStm >> nTmp16; rImpl_Font.meCharSet = (rtl_TextEncoding) nTmp16;
694 25767 : rIStm >> nTmp16; rImpl_Font.meFamily = (FontFamily) nTmp16;
695 25767 : rIStm >> nTmp16; rImpl_Font.mePitch = (FontPitch) nTmp16;
696 25767 : rIStm >> nTmp16; rImpl_Font.meWeight = (FontWeight) nTmp16;
697 25767 : rIStm >> nTmp16; rImpl_Font.meUnderline = (FontUnderline) nTmp16;
698 25767 : rIStm >> nTmp16; rImpl_Font.meStrikeout = (FontStrikeout) nTmp16;
699 25767 : rIStm >> nTmp16; rImpl_Font.meItalic = (FontItalic) nTmp16;
700 25767 : rIStm >> nTmp16; rImpl_Font.meLanguage = (LanguageType) nTmp16;
701 25767 : rIStm >> nTmp16; rImpl_Font.meWidthType = (FontWidth) nTmp16;
702 :
703 25767 : rIStm >> rImpl_Font.mnOrientation;
704 :
705 25767 : rIStm >> bTmp; rImpl_Font.mbWordLine = bTmp;
706 25767 : rIStm >> bTmp; rImpl_Font.mbOutline = bTmp;
707 25767 : rIStm >> bTmp; rImpl_Font.mbShadow = bTmp;
708 25767 : rIStm >> nTmp8; rImpl_Font.mnKerning = nTmp8;
709 :
710 25767 : if( aCompat.GetVersion() >= 2 )
711 : {
712 25767 : rIStm >> nTmp8; rImpl_Font.meRelief = (FontRelief)nTmp8;
713 25767 : rIStm >> nTmp16; rImpl_Font.meCJKLanguage = (LanguageType)nTmp16;
714 25767 : rIStm >> bTmp; rImpl_Font.mbVertical = bTmp;
715 25767 : rIStm >> nTmp16; rImpl_Font.meEmphasisMark = (FontEmphasisMark)nTmp16;
716 : }
717 25767 : if( aCompat.GetVersion() >= 3 )
718 : {
719 25767 : rIStm >> nTmp16; rImpl_Font.meOverline = (FontUnderline) nTmp16;
720 : }
721 : // Relief
722 : // CJKContextLanguage
723 :
724 25767 : return rIStm;
725 : }
726 :
727 27508 : SvStream& operator<<( SvStream& rOStm, const Impl_Font& rImpl_Font )
728 : {
729 27508 : VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
730 27508 : rOStm.WriteUniOrByteString( rImpl_Font.maFamilyName, rOStm.GetStreamCharSet() );
731 27508 : rOStm.WriteUniOrByteString( rImpl_Font.maStyleName, rOStm.GetStreamCharSet() );
732 27508 : rOStm << rImpl_Font.maSize;
733 :
734 27508 : rOStm << (sal_uInt16) GetStoreCharSet( rImpl_Font.meCharSet );
735 27508 : rOStm << (sal_uInt16) rImpl_Font.meFamily;
736 27508 : rOStm << (sal_uInt16) rImpl_Font.mePitch;
737 27508 : rOStm << (sal_uInt16) rImpl_Font.meWeight;
738 27508 : rOStm << (sal_uInt16) rImpl_Font.meUnderline;
739 27508 : rOStm << (sal_uInt16) rImpl_Font.meStrikeout;
740 27508 : rOStm << (sal_uInt16) rImpl_Font.meItalic;
741 27508 : rOStm << (sal_uInt16) rImpl_Font.meLanguage;
742 27508 : rOStm << (sal_uInt16) rImpl_Font.meWidthType;
743 :
744 27508 : rOStm << rImpl_Font.mnOrientation;
745 :
746 27508 : rOStm << (sal_Bool) rImpl_Font.mbWordLine;
747 27508 : rOStm << (sal_Bool) rImpl_Font.mbOutline;
748 27508 : rOStm << (sal_Bool) rImpl_Font.mbShadow;
749 27508 : rOStm << (sal_uInt8) rImpl_Font.mnKerning;
750 :
751 : // new in version 2
752 27508 : rOStm << (sal_uInt8) rImpl_Font.meRelief;
753 27508 : rOStm << (sal_uInt16) rImpl_Font.meCJKLanguage;
754 27508 : rOStm << (sal_Bool) rImpl_Font.mbVertical;
755 27508 : rOStm << (sal_uInt16) rImpl_Font.meEmphasisMark;
756 :
757 : // new in version 3
758 27508 : rOStm << (sal_uInt16) rImpl_Font.meOverline;
759 :
760 27508 : return rOStm;
761 : }
762 :
763 25767 : SvStream& operator>>( SvStream& rIStm, Font& rFont )
764 : {
765 25767 : rFont.MakeUnique();
766 25767 : return( rIStm >> *rFont.mpImplFont );
767 : }
768 :
769 27508 : SvStream& operator<<( SvStream& rOStm, const Font& rFont )
770 : {
771 27508 : return( rOStm << *rFont.mpImplFont );
772 : }
773 :
774 : namespace
775 : {
776 0 : bool identifyTrueTypeFont( const void* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
777 : {
778 0 : bool bResult = false;
779 0 : TrueTypeFont* pTTF = NULL;
780 0 : if( OpenTTFontBuffer( const_cast<void*>(i_pBuffer), i_nSize, 0, &pTTF ) == SF_OK )
781 : {
782 : TTGlobalFontInfo aInfo;
783 0 : GetTTGlobalFontInfo( pTTF, &aInfo );
784 : // most importantly: the family name
785 0 : if( aInfo.ufamily )
786 0 : o_rResult.SetName( aInfo.ufamily );
787 0 : else if( aInfo.family )
788 0 : o_rResult.SetName( OStringToOUString( aInfo.family, RTL_TEXTENCODING_ASCII_US ) );
789 : // set weight
790 0 : if( aInfo.weight )
791 : {
792 0 : if( aInfo.weight < FW_EXTRALIGHT )
793 0 : o_rResult.SetWeight( WEIGHT_THIN );
794 0 : else if( aInfo.weight < FW_LIGHT )
795 0 : o_rResult.SetWeight( WEIGHT_ULTRALIGHT );
796 0 : else if( aInfo.weight < FW_NORMAL )
797 0 : o_rResult.SetWeight( WEIGHT_LIGHT );
798 0 : else if( aInfo.weight < FW_MEDIUM )
799 0 : o_rResult.SetWeight( WEIGHT_NORMAL );
800 0 : else if( aInfo.weight < FW_SEMIBOLD )
801 0 : o_rResult.SetWeight( WEIGHT_MEDIUM );
802 0 : else if( aInfo.weight < FW_BOLD )
803 0 : o_rResult.SetWeight( WEIGHT_SEMIBOLD );
804 0 : else if( aInfo.weight < FW_EXTRABOLD )
805 0 : o_rResult.SetWeight( WEIGHT_BOLD );
806 0 : else if( aInfo.weight < FW_BLACK )
807 0 : o_rResult.SetWeight( WEIGHT_ULTRABOLD );
808 : else
809 0 : o_rResult.SetWeight( WEIGHT_BLACK );
810 : }
811 : else
812 0 : o_rResult.SetWeight( (aInfo.macStyle & 1) ? WEIGHT_BOLD : WEIGHT_NORMAL );
813 : // set width
814 0 : if( aInfo.width )
815 : {
816 0 : if( aInfo.width == FWIDTH_ULTRA_CONDENSED )
817 0 : o_rResult.SetWidth( WIDTH_ULTRA_CONDENSED );
818 0 : else if( aInfo.width == FWIDTH_EXTRA_CONDENSED )
819 0 : o_rResult.SetWidth( WIDTH_EXTRA_CONDENSED );
820 0 : else if( aInfo.width == FWIDTH_CONDENSED )
821 0 : o_rResult.SetWidth( WIDTH_CONDENSED );
822 0 : else if( aInfo.width == FWIDTH_SEMI_CONDENSED )
823 0 : o_rResult.SetWidth( WIDTH_SEMI_CONDENSED );
824 0 : else if( aInfo.width == FWIDTH_NORMAL )
825 0 : o_rResult.SetWidth( WIDTH_NORMAL );
826 0 : else if( aInfo.width == FWIDTH_SEMI_EXPANDED )
827 0 : o_rResult.SetWidth( WIDTH_SEMI_EXPANDED );
828 0 : else if( aInfo.width == FWIDTH_EXPANDED )
829 0 : o_rResult.SetWidth( WIDTH_EXPANDED );
830 0 : else if( aInfo.width == FWIDTH_EXTRA_EXPANDED )
831 0 : o_rResult.SetWidth( WIDTH_EXTRA_EXPANDED );
832 0 : else if( aInfo.width >= FWIDTH_ULTRA_EXPANDED )
833 0 : o_rResult.SetWidth( WIDTH_ULTRA_EXPANDED );
834 : }
835 : // set italic
836 0 : o_rResult.SetItalic( (aInfo.italicAngle != 0) ? ITALIC_NORMAL : ITALIC_NONE );
837 :
838 : // set pitch
839 0 : o_rResult.SetPitch( (aInfo.pitch == 0) ? PITCH_VARIABLE : PITCH_FIXED );
840 :
841 : // set style name
842 0 : if( aInfo.usubfamily )
843 0 : o_rResult.SetStyleName( OUString( aInfo.usubfamily ) );
844 0 : else if( aInfo.subfamily )
845 0 : o_rResult.SetStyleName( OUString::createFromAscii( aInfo.subfamily ) );
846 :
847 : // cleanup
848 0 : CloseTTFont( pTTF );
849 : // success
850 0 : bResult = true;
851 : }
852 0 : return bResult;
853 : }
854 :
855 : struct WeightSearchEntry
856 : {
857 : const char* string;
858 : int string_len;
859 : FontWeight weight;
860 :
861 0 : bool operator<( const WeightSearchEntry& rRight ) const
862 : {
863 0 : return rtl_str_compareIgnoreAsciiCase_WithLength( string, string_len, rRight.string, rRight.string_len ) < 0;
864 : }
865 : }
866 : weight_table[] =
867 : {
868 : { "black", 5, WEIGHT_BLACK },
869 : { "bold", 4, WEIGHT_BOLD },
870 : { "book", 4, WEIGHT_LIGHT },
871 : { "demi", 4, WEIGHT_SEMIBOLD },
872 : { "heavy", 5, WEIGHT_BLACK },
873 : { "light", 5, WEIGHT_LIGHT },
874 : { "medium", 6, WEIGHT_MEDIUM },
875 : { "regular", 7, WEIGHT_NORMAL },
876 : { "super", 5, WEIGHT_ULTRABOLD },
877 : { "thin", 4, WEIGHT_THIN }
878 : };
879 :
880 0 : bool identifyType1Font( const char* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
881 : {
882 0 : bool bResult = false;
883 : // might be a type1, find eexec
884 0 : const char* pStream = i_pBuffer;
885 0 : const char* pExec = "eexec";
886 0 : const char* pExecPos = std::search( pStream, pStream+i_nSize, pExec, pExec+5 );
887 0 : if( pExecPos != pStream+i_nSize)
888 : {
889 : // find /FamilyName entry
890 : static const char* pFam = "/FamilyName";
891 0 : const char* pFamPos = std::search( pStream, pExecPos, pFam, pFam+11 );
892 0 : if( pFamPos != pExecPos )
893 : {
894 : // extract the string value behind /FamilyName
895 0 : const char* pOpen = pFamPos+11;
896 0 : while( pOpen < pExecPos && *pOpen != '(' )
897 0 : pOpen++;
898 0 : const char* pClose = pOpen;
899 0 : while( pClose < pExecPos && *pClose != ')' )
900 0 : pClose++;
901 0 : if( pClose - pOpen > 1 )
902 : {
903 0 : o_rResult.SetName( OStringToOUString( OString( pOpen+1, pClose-pOpen-1 ), RTL_TEXTENCODING_ASCII_US ) );
904 : }
905 : }
906 :
907 : // parse /ItalicAngle
908 : static const char* pItalic = "/ItalicAngle";
909 0 : const char* pItalicPos = std::search( pStream, pExecPos, pItalic, pItalic+12 );
910 0 : if( pItalicPos != pExecPos )
911 : {
912 0 : sal_Int32 nItalic = rtl_str_toInt32( pItalicPos+12, 10 );
913 0 : o_rResult.SetItalic( (nItalic != 0) ? ITALIC_NORMAL : ITALIC_NONE );
914 : }
915 :
916 : // parse /Weight
917 : static const char* pWeight = "/Weight";
918 0 : const char* pWeightPos = std::search( pStream, pExecPos, pWeight, pWeight+7 );
919 0 : if( pWeightPos != pExecPos )
920 : {
921 : // extract the string value behind /Weight
922 0 : const char* pOpen = pWeightPos+7;
923 0 : while( pOpen < pExecPos && *pOpen != '(' )
924 0 : pOpen++;
925 0 : const char* pClose = pOpen;
926 0 : while( pClose < pExecPos && *pClose != ')' )
927 0 : pClose++;
928 0 : if( pClose - pOpen > 1 )
929 : {
930 : WeightSearchEntry aEnt;
931 0 : aEnt.string = pOpen+1;
932 0 : aEnt.string_len = (pClose-pOpen)-1;
933 0 : aEnt.weight = WEIGHT_NORMAL;
934 0 : const int nEnt = SAL_N_ELEMENTS( weight_table );
935 0 : WeightSearchEntry* pFound = std::lower_bound( weight_table, weight_table+nEnt, aEnt );
936 0 : if( pFound != (weight_table+nEnt) )
937 0 : o_rResult.SetWeight( pFound->weight );
938 : }
939 : }
940 :
941 : // parse isFixedPitch
942 : static const char* pFixed = "/isFixedPitch";
943 0 : const char* pFixedPos = std::search( pStream, pExecPos, pFixed, pFixed+13 );
944 0 : if( pFixedPos != pExecPos )
945 : {
946 : // skip whitespace
947 0 : while( pFixedPos < pExecPos-4 &&
948 0 : ( *pFixedPos == ' ' ||
949 0 : *pFixedPos == '\t' ||
950 0 : *pFixedPos == '\r' ||
951 0 : *pFixedPos == '\n' ) )
952 : {
953 0 : pFixedPos++;
954 : }
955 : // find "true" value
956 0 : if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos, 4, "true", 4 ) == 0 )
957 0 : o_rResult.SetPitch( PITCH_FIXED );
958 : else
959 0 : o_rResult.SetPitch( PITCH_VARIABLE );
960 : }
961 : }
962 0 : return bResult;
963 : }
964 : }
965 :
966 0 : Font Font::identifyFont( const void* i_pBuffer, sal_uInt32 i_nSize )
967 : {
968 0 : Font aResult;
969 0 : if( ! identifyTrueTypeFont( i_pBuffer, i_nSize, aResult ) )
970 : {
971 0 : const char* pStream = reinterpret_cast<const char*>(i_pBuffer);
972 0 : if( pStream && i_nSize > 100 &&
973 0 : *pStream == '%' && pStream[1] == '!' )
974 : {
975 0 : identifyType1Font( pStream, i_nSize, aResult );
976 : }
977 : }
978 :
979 0 : return aResult;
980 : }
981 :
982 : // The inlines from the font.hxx header are now instantiated for pImpl-ification
983 2564822 : const Color& Font::GetColor() const { return mpImplFont->maColor; }
984 :
985 47873 : const Color& Font::GetFillColor() const { return mpImplFont->maFillColor; }
986 :
987 287217 : sal_Bool Font::IsTransparent() const { return mpImplFont->mbTransparent; }
988 :
989 1038058 : FontAlign Font::GetAlign() const { return mpImplFont->meAlign; }
990 :
991 2074344 : const String& Font::GetName() const { return mpImplFont->maFamilyName; }
992 :
993 22233 : const String& Font::GetStyleName() const { return mpImplFont->maStyleName; }
994 :
995 2863008 : const Size& Font::GetSize() const { return mpImplFont->maSize; }
996 :
997 59807 : void Font::SetHeight( long nHeight ) { SetSize( Size( mpImplFont->maSize.Width(), nHeight ) ); }
998 :
999 1577515 : long Font::GetHeight() const { return mpImplFont->maSize.Height(); }
1000 :
1001 0 : void Font::SetWidth( long nWidth ) { SetSize( Size( nWidth, mpImplFont->maSize.Height() ) ); }
1002 :
1003 137 : long Font::GetWidth() const { return mpImplFont->maSize.Width(); }
1004 :
1005 219293 : rtl_TextEncoding Font::GetCharSet() const { return mpImplFont->meCharSet; }
1006 :
1007 2475189 : LanguageType Font::GetLanguage() const { return mpImplFont->meLanguage; }
1008 :
1009 9559 : LanguageType Font::GetCJKContextLanguage() const { return mpImplFont->meCJKLanguage; }
1010 :
1011 831240 : short Font::GetOrientation() const { return mpImplFont->mnOrientation; }
1012 :
1013 1553414 : sal_Bool Font::IsVertical() const { return mpImplFont->mbVertical; }
1014 :
1015 2952414 : FontKerning Font::GetKerning() const { return mpImplFont->mnKerning; }
1016 :
1017 32085 : FontPitch Font::GetPitch() const { return mpImplFont->GetPitch(); }
1018 :
1019 305725 : FontWeight Font::GetWeight() const { return mpImplFont->GetWeight(); }
1020 :
1021 3745 : FontWidth Font::GetWidthType() const { return mpImplFont->GetWidthType(); }
1022 :
1023 1480517 : FontItalic Font::GetItalic() const { return mpImplFont->GetItalic(); }
1024 :
1025 22108 : FontFamily Font::GetFamily() const { return mpImplFont->GetFamily(); }
1026 :
1027 747251 : sal_Bool Font::IsOutline() const { return mpImplFont->mbOutline; }
1028 :
1029 762574 : sal_Bool Font::IsShadow() const { return mpImplFont->mbShadow; }
1030 :
1031 751227 : FontRelief Font::GetRelief() const { return mpImplFont->meRelief; }
1032 :
1033 1030209 : FontUnderline Font::GetUnderline() const { return mpImplFont->meUnderline; }
1034 :
1035 889621 : FontUnderline Font::GetOverline() const { return mpImplFont->meOverline; }
1036 :
1037 882525 : FontStrikeout Font::GetStrikeout() const { return mpImplFont->meStrikeout; }
1038 :
1039 897854 : FontEmphasisMark Font::GetEmphasisMark() const { return mpImplFont->meEmphasisMark; }
1040 :
1041 620954 : sal_Bool Font::IsWordLineMode() const { return mpImplFont->mbWordLine; }
1042 :
1043 1891533 : sal_Bool Font::IsSameInstance( const Font& rFont ) const { return (mpImplFont == rFont.mpImplFont); }
1044 :
1045 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|