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 :
27 : #include "vcl/font.hxx"
28 :
29 : #include "impfont.hxx"
30 : #include "outfont.hxx"
31 : #include "sft.hxx"
32 :
33 : #include <sal/macros.h>
34 :
35 : #include <algorithm>
36 :
37 : using namespace vcl;
38 :
39 : // =======================================================================
40 :
41 : DBG_NAME( Font )
42 :
43 : // -----------------------------------------------------------------------
44 :
45 5362 : Impl_Font::Impl_Font() :
46 : maColor( COL_TRANSPARENT ),
47 5362 : maFillColor( COL_TRANSPARENT )
48 : {
49 5362 : mnRefCount = 1;
50 5362 : meCharSet = RTL_TEXTENCODING_DONTKNOW;
51 5362 : meLanguage = LANGUAGE_DONTKNOW;
52 5362 : meCJKLanguage = LANGUAGE_DONTKNOW;
53 5362 : meFamily = FAMILY_DONTKNOW;
54 5362 : mePitch = PITCH_DONTKNOW;
55 5362 : meAlign = ALIGN_TOP;
56 5362 : meWeight = WEIGHT_DONTKNOW;
57 5362 : meWidthType = WIDTH_DONTKNOW;
58 5362 : meItalic = ITALIC_NONE;
59 5362 : meUnderline = UNDERLINE_NONE;
60 5362 : meOverline = UNDERLINE_NONE;
61 5362 : meStrikeout = STRIKEOUT_NONE;
62 5362 : meRelief = RELIEF_NONE;
63 5362 : meEmphasisMark = EMPHASISMARK_NONE;
64 5362 : mnOrientation = 0;
65 5362 : mnKerning = 0;
66 5362 : mbWordLine = false;
67 5362 : mbOutline = false;
68 5362 : mbShadow = false;
69 5362 : mbVertical = false;
70 5362 : mbTransparent = true;
71 5362 : mbConfigLookup = false;
72 5362 : }
73 :
74 : // -----------------------------------------------------------------------
75 :
76 282701 : Impl_Font::Impl_Font( const Impl_Font& rImplFont )
77 : : maFamilyName( rImplFont.maFamilyName ),
78 : maStyleName( rImplFont.maStyleName ),
79 : maSize( rImplFont.maSize ),
80 : maColor( rImplFont.maColor ),
81 282701 : maFillColor( rImplFont.maFillColor )
82 : {
83 282701 : mnRefCount = 1;
84 282701 : meCharSet = rImplFont.meCharSet;
85 282701 : meLanguage = rImplFont.meLanguage;
86 282701 : meCJKLanguage = rImplFont.meCJKLanguage;
87 282701 : meFamily = rImplFont.meFamily;
88 282701 : mePitch = rImplFont.mePitch;
89 282701 : meAlign = rImplFont.meAlign;
90 282701 : meWeight = rImplFont.meWeight;
91 282701 : meWidthType = rImplFont.meWidthType;
92 282701 : meItalic = rImplFont.meItalic;
93 282701 : meUnderline = rImplFont.meUnderline;
94 282701 : meOverline = rImplFont.meOverline;
95 282701 : meStrikeout = rImplFont.meStrikeout;
96 282701 : meRelief = rImplFont.meRelief;
97 282701 : meEmphasisMark = rImplFont.meEmphasisMark;
98 282701 : mnOrientation = rImplFont.mnOrientation;
99 282701 : mnKerning = rImplFont.mnKerning;
100 282701 : mbWordLine = rImplFont.mbWordLine;
101 282701 : mbOutline = rImplFont.mbOutline;
102 282701 : mbShadow = rImplFont.mbShadow;
103 282701 : mbVertical = rImplFont.mbVertical;
104 282701 : mbTransparent = rImplFont.mbTransparent;
105 282701 : mbConfigLookup = rImplFont.mbConfigLookup;
106 282701 : }
107 :
108 : // -----------------------------------------------------------------------
109 :
110 67750 : bool Impl_Font::operator==( const Impl_Font& rOther ) const
111 : {
112 : // equality tests split up for easier debugging
113 67750 : if( (meWeight != rOther.meWeight)
114 : || (meItalic != rOther.meItalic)
115 : || (meFamily != rOther.meFamily)
116 : || (mePitch != rOther.mePitch) )
117 10848 : return false;
118 :
119 56902 : if( (meCharSet != rOther.meCharSet)
120 : || (meLanguage != rOther.meLanguage)
121 : || (meCJKLanguage != rOther.meCJKLanguage)
122 : || (meAlign != rOther.meAlign) )
123 5700 : return false;
124 :
125 51202 : if( (maSize != rOther.maSize)
126 : || (mnOrientation != rOther.mnOrientation)
127 : || (mbVertical != rOther.mbVertical) )
128 3376 : return false;
129 :
130 95599 : if( (maFamilyName != rOther.maFamilyName)
131 47773 : || (maStyleName != rOther.maStyleName) )
132 53 : return false;
133 :
134 95485 : if( (maColor != rOther.maColor)
135 47712 : || (maFillColor != rOther.maFillColor) )
136 61 : return false;
137 :
138 47712 : if( (meUnderline != rOther.meUnderline)
139 : || (meOverline != rOther.meOverline)
140 : || (meStrikeout != rOther.meStrikeout)
141 : || (meRelief != rOther.meRelief)
142 : || (meEmphasisMark != rOther.meEmphasisMark)
143 : || (mbWordLine != rOther.mbWordLine)
144 : || (mbOutline != rOther.mbOutline)
145 : || (mbShadow != rOther.mbShadow)
146 : || (mnKerning != rOther.mnKerning)
147 : || (mbTransparent != rOther.mbTransparent) )
148 113 : return false;
149 :
150 47599 : return true;
151 : }
152 :
153 : // -----------------------------------------------------------------------
154 :
155 13188 : void Impl_Font::AskConfig()
156 : {
157 13188 : if( mbConfigLookup )
158 13188 : return;
159 :
160 4851 : mbConfigLookup = true;
161 :
162 : // prepare the FontSubst configuration lookup
163 4851 : const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
164 :
165 4851 : String aShortName;
166 4851 : String aFamilyName;
167 4851 : sal_uLong nType = 0;
168 4851 : FontWeight eWeight = WEIGHT_DONTKNOW;
169 4851 : FontWidth eWidthType = WIDTH_DONTKNOW;
170 4851 : String aMapName = maFamilyName;
171 4851 : GetEnglishSearchFontName( aMapName );
172 : utl::FontSubstConfiguration::getMapName( aMapName,
173 4851 : aShortName, aFamilyName, eWeight, eWidthType, nType );
174 :
175 : // lookup the font name in the configuration
176 4851 : const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
177 :
178 : // if the direct lookup failed try again with an alias name
179 4851 : if ( !pFontAttr && (aShortName != aMapName) )
180 257 : pFontAttr = rFontSubst.getSubstInfo( aShortName );
181 :
182 4851 : if( pFontAttr )
183 : {
184 : // the font was found in the configuration
185 3278 : if( meFamily == FAMILY_DONTKNOW )
186 : {
187 2748 : if ( pFontAttr->Type & IMPL_FONT_ATTR_SERIF )
188 1047 : meFamily = FAMILY_ROMAN;
189 1701 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_SANSSERIF )
190 268 : meFamily = FAMILY_SWISS;
191 1433 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_TYPEWRITER )
192 6 : meFamily = FAMILY_MODERN;
193 1427 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_ITALIC )
194 0 : meFamily = FAMILY_SCRIPT;
195 1427 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_DECORATIVE )
196 0 : meFamily = FAMILY_DECORATIVE;
197 : }
198 :
199 3278 : if( mePitch == PITCH_DONTKNOW )
200 : {
201 3278 : if ( pFontAttr->Type & IMPL_FONT_ATTR_FIXED )
202 6 : mePitch = PITCH_FIXED;
203 : }
204 : }
205 :
206 : // if some attributes are still unknown then use the FontSubst magic
207 4851 : if( meFamily == FAMILY_DONTKNOW )
208 : {
209 2998 : if( nType & IMPL_FONT_ATTR_SERIF )
210 0 : meFamily = FAMILY_ROMAN;
211 2998 : else if( nType & IMPL_FONT_ATTR_SANSSERIF )
212 0 : meFamily = FAMILY_SWISS;
213 2998 : else if( nType & IMPL_FONT_ATTR_TYPEWRITER )
214 0 : meFamily = FAMILY_MODERN;
215 2998 : else if( nType & IMPL_FONT_ATTR_ITALIC )
216 0 : meFamily = FAMILY_SCRIPT;
217 2998 : else if( nType & IMPL_FONT_ATTR_DECORATIVE )
218 0 : meFamily = FAMILY_DECORATIVE;
219 : }
220 :
221 4851 : if( meWeight == WEIGHT_DONTKNOW )
222 4043 : meWeight = eWeight;
223 4851 : if( meWidthType == WIDTH_DONTKNOW )
224 4851 : meWidthType = eWidthType;
225 : }
226 :
227 : // =======================================================================
228 :
229 1018785 : void Font::MakeUnique()
230 : {
231 : // create a copy if others still reference it
232 1018785 : if ( mpImplFont->mnRefCount != 1 )
233 : {
234 282701 : if ( mpImplFont->mnRefCount )
235 170237 : mpImplFont->mnRefCount--;
236 282701 : mpImplFont = new Impl_Font( *mpImplFont );
237 : }
238 1018785 : }
239 :
240 : // -----------------------------------------------------------------------
241 :
242 267797 : Font::Font()
243 : {
244 : DBG_CTOR( Font, NULL );
245 :
246 267797 : static Impl_Font aStaticImplFont;
247 : // RefCount is zero for static objects
248 267797 : aStaticImplFont.mnRefCount = 0;
249 267797 : mpImplFont = &aStaticImplFont;
250 267797 : }
251 :
252 : // -----------------------------------------------------------------------
253 :
254 430223 : Font::Font( const Font& rFont )
255 : {
256 : DBG_CTOR( Font, NULL );
257 : DBG_CHKOBJ( &rFont, Font, NULL );
258 : DBG_ASSERT( rFont.mpImplFont->mnRefCount < 0xFFFE, "Font: RefCount overflow" );
259 :
260 430223 : mpImplFont = rFont.mpImplFont;
261 : // do not count static objects (where RefCount is zero)
262 430223 : if ( mpImplFont->mnRefCount )
263 424655 : mpImplFont->mnRefCount++;
264 430223 : }
265 :
266 : // -----------------------------------------------------------------------
267 :
268 5051 : Font::Font( const String& rFamilyName, const Size& rSize )
269 : {
270 : DBG_CTOR( Font, NULL );
271 :
272 5051 : mpImplFont = new Impl_Font;
273 5051 : mpImplFont->maFamilyName= rFamilyName;
274 5051 : mpImplFont->maSize = rSize;
275 5051 : }
276 :
277 : // -----------------------------------------------------------------------
278 :
279 259 : Font::Font( const String& rFamilyName, const String& rStyleName, const Size& rSize )
280 : {
281 : DBG_CTOR( Font, NULL );
282 :
283 259 : mpImplFont = new Impl_Font;
284 259 : mpImplFont->maFamilyName= rFamilyName;
285 259 : mpImplFont->maStyleName = rStyleName;
286 259 : mpImplFont->maSize = rSize;
287 259 : }
288 :
289 : // -----------------------------------------------------------------------
290 :
291 26 : Font::Font( FontFamily eFamily, const Size& rSize )
292 : {
293 : DBG_CTOR( Font, NULL );
294 :
295 26 : mpImplFont = new Impl_Font;
296 26 : mpImplFont->meFamily = eFamily;
297 26 : mpImplFont->maSize = rSize;
298 26 : }
299 :
300 : // -----------------------------------------------------------------------
301 :
302 660199 : Font::~Font()
303 : {
304 : DBG_DTOR( Font, NULL );
305 :
306 : // decrement reference counter and delete if last reference
307 : // if the object is not static (Refcounter==0)
308 660199 : if ( mpImplFont->mnRefCount )
309 : {
310 651123 : if ( mpImplFont->mnRefCount == 1 )
311 168495 : delete mpImplFont;
312 : else
313 482628 : mpImplFont->mnRefCount--;
314 : }
315 660199 : }
316 :
317 : // -----------------------------------------------------------------------
318 :
319 93891 : void Font::SetColor( const Color& rColor )
320 : {
321 : DBG_CHKTHIS( Font, NULL );
322 :
323 93891 : if( mpImplFont->maColor != rColor )
324 : {
325 14464 : MakeUnique();
326 14464 : mpImplFont->maColor = rColor;
327 : }
328 93891 : }
329 :
330 : // -----------------------------------------------------------------------
331 :
332 672 : void Font::SetFillColor( const Color& rColor )
333 : {
334 : DBG_CHKTHIS( Font, NULL );
335 :
336 672 : MakeUnique();
337 672 : mpImplFont->maFillColor = rColor;
338 672 : if ( rColor.GetTransparency() )
339 601 : mpImplFont->mbTransparent = true;
340 672 : }
341 :
342 : // -----------------------------------------------------------------------
343 :
344 102514 : void Font::SetTransparent( sal_Bool bTransparent )
345 : {
346 : DBG_CHKTHIS( Font, NULL );
347 :
348 102514 : if( mpImplFont->mbTransparent != bTransparent )
349 : {
350 6 : MakeUnique();
351 6 : mpImplFont->mbTransparent = bTransparent;
352 : }
353 102514 : }
354 :
355 : // -----------------------------------------------------------------------
356 :
357 117244 : void Font::SetAlign( FontAlign eAlign )
358 : {
359 : DBG_CHKTHIS( Font, NULL );
360 :
361 117244 : if( mpImplFont->meAlign != eAlign )
362 : {
363 31672 : MakeUnique();
364 31672 : mpImplFont->meAlign = eAlign;
365 : }
366 117244 : }
367 :
368 : // -----------------------------------------------------------------------
369 :
370 200907 : void Font::SetName( const rtl::OUString& rFamilyName )
371 : {
372 : DBG_CHKTHIS( Font, NULL );
373 :
374 200907 : MakeUnique();
375 200907 : mpImplFont->maFamilyName = rFamilyName;
376 200907 : }
377 :
378 : // -----------------------------------------------------------------------
379 :
380 98311 : void Font::SetStyleName( const String& rStyleName )
381 : {
382 : DBG_CHKTHIS( Font, NULL );
383 :
384 98311 : MakeUnique();
385 98311 : mpImplFont->maStyleName = rStyleName;
386 98311 : }
387 :
388 : // -----------------------------------------------------------------------
389 :
390 181617 : void Font::SetSize( const Size& rSize )
391 : {
392 : DBG_CHKTHIS( Font, NULL );
393 :
394 181617 : if( mpImplFont->maSize != rSize )
395 : {
396 119184 : MakeUnique();
397 119184 : mpImplFont->maSize = rSize;
398 : }
399 181617 : }
400 :
401 : // -----------------------------------------------------------------------
402 :
403 185248 : void Font::SetFamily( FontFamily eFamily )
404 : {
405 : DBG_CHKTHIS( Font, NULL );
406 :
407 185248 : if( mpImplFont->meFamily != eFamily )
408 : {
409 68350 : MakeUnique();
410 68350 : mpImplFont->meFamily = eFamily;
411 : }
412 185248 : }
413 :
414 : // -----------------------------------------------------------------------
415 :
416 186190 : void Font::SetCharSet( CharSet eCharSet )
417 : {
418 : DBG_CHKTHIS( Font, NULL );
419 :
420 186190 : if( mpImplFont->meCharSet != eCharSet )
421 : {
422 123722 : MakeUnique();
423 123722 : mpImplFont->meCharSet = eCharSet;
424 : }
425 186190 : }
426 :
427 : // -----------------------------------------------------------------------
428 :
429 212364 : void Font::SetLanguage( LanguageType eLanguage )
430 : {
431 : DBG_CHKTHIS( Font, NULL );
432 :
433 212364 : if( mpImplFont->meLanguage != eLanguage )
434 : {
435 26791 : MakeUnique();
436 26791 : mpImplFont->meLanguage = eLanguage;
437 : }
438 212364 : }
439 :
440 : // -----------------------------------------------------------------------
441 :
442 44648 : void Font::SetCJKContextLanguage( LanguageType eLanguage )
443 : {
444 : DBG_CHKTHIS( Font, NULL );
445 :
446 44648 : if( mpImplFont->meCJKLanguage != eLanguage )
447 : {
448 27625 : MakeUnique();
449 27625 : mpImplFont->meCJKLanguage = eLanguage;
450 : }
451 44648 : }
452 :
453 : // -----------------------------------------------------------------------
454 :
455 185433 : void Font::SetPitch( FontPitch ePitch )
456 : {
457 : DBG_CHKTHIS( Font, NULL );
458 :
459 185433 : if( mpImplFont->mePitch != ePitch )
460 : {
461 88449 : MakeUnique();
462 88449 : mpImplFont->mePitch = ePitch;
463 : }
464 185433 : }
465 :
466 : // -----------------------------------------------------------------------
467 :
468 64147 : void Font::SetOrientation( short nOrientation )
469 : {
470 : DBG_CHKTHIS( Font, NULL );
471 :
472 64147 : if( mpImplFont->mnOrientation != nOrientation )
473 : {
474 765 : MakeUnique();
475 765 : mpImplFont->mnOrientation = nOrientation;
476 : }
477 64147 : }
478 :
479 : // -----------------------------------------------------------------------
480 :
481 18565 : void Font::SetVertical( sal_Bool bVertical )
482 : {
483 : DBG_CHKTHIS( Font, NULL );
484 :
485 18565 : if( mpImplFont->mbVertical != bVertical )
486 : {
487 0 : MakeUnique();
488 0 : mpImplFont->mbVertical = bVertical;
489 : }
490 18565 : }
491 :
492 : // -----------------------------------------------------------------------
493 :
494 103124 : void Font::SetKerning( FontKerning nKerning )
495 : {
496 : DBG_CHKTHIS( Font, NULL );
497 :
498 103124 : if( mpImplFont->mnKerning != nKerning )
499 : {
500 6788 : MakeUnique();
501 6788 : mpImplFont->mnKerning = nKerning;
502 : }
503 103124 : }
504 :
505 : // -----------------------------------------------------------------------
506 :
507 29 : sal_Bool Font::IsKerning() const
508 : {
509 29 : return (mpImplFont->mnKerning & KERNING_FONTSPECIFIC) != 0;
510 : }
511 :
512 : // -----------------------------------------------------------------------
513 :
514 198929 : void Font::SetWeight( FontWeight eWeight )
515 : {
516 : DBG_CHKTHIS( Font, NULL );
517 :
518 198929 : if( mpImplFont->meWeight != eWeight )
519 : {
520 97537 : MakeUnique();
521 97537 : mpImplFont->meWeight = eWeight;
522 : }
523 198929 : }
524 :
525 : // -----------------------------------------------------------------------
526 :
527 94811 : void Font::SetWidthType( FontWidth eWidth )
528 : {
529 : DBG_CHKTHIS( Font, NULL );
530 :
531 94811 : if( mpImplFont->meWidthType != eWidth )
532 : {
533 74159 : MakeUnique();
534 74159 : mpImplFont->meWidthType = eWidth;
535 : }
536 94811 : }
537 :
538 : // -----------------------------------------------------------------------
539 :
540 178875 : void Font::SetItalic( FontItalic eItalic )
541 : {
542 : DBG_CHKTHIS( Font, NULL );
543 :
544 178875 : if( mpImplFont->meItalic != eItalic )
545 : {
546 17222 : MakeUnique();
547 17222 : mpImplFont->meItalic = eItalic;
548 : }
549 178875 : }
550 :
551 : // -----------------------------------------------------------------------
552 :
553 66080 : void Font::SetOutline( sal_Bool bOutline )
554 : {
555 : DBG_CHKTHIS( Font, NULL );
556 :
557 66080 : if( mpImplFont->mbOutline != bOutline )
558 : {
559 0 : MakeUnique();
560 0 : mpImplFont->mbOutline = bOutline;
561 : }
562 66080 : }
563 :
564 : // -----------------------------------------------------------------------
565 :
566 65849 : void Font::SetShadow( sal_Bool bShadow )
567 : {
568 : DBG_CHKTHIS( Font, NULL );
569 :
570 65849 : if( mpImplFont->mbShadow != bShadow )
571 : {
572 4 : MakeUnique();
573 4 : mpImplFont->mbShadow = bShadow;
574 : }
575 65849 : }
576 :
577 : // -----------------------------------------------------------------------
578 :
579 66525 : void Font::SetUnderline( FontUnderline eUnderline )
580 : {
581 : DBG_CHKTHIS( Font, NULL );
582 :
583 66525 : if( mpImplFont->meUnderline != eUnderline )
584 : {
585 134 : MakeUnique();
586 134 : mpImplFont->meUnderline = eUnderline;
587 : }
588 66525 : }
589 :
590 : // -----------------------------------------------------------------------
591 :
592 65778 : void Font::SetOverline( FontUnderline eOverline )
593 : {
594 : DBG_CHKTHIS( Font, NULL );
595 :
596 65778 : if( mpImplFont->meOverline != eOverline )
597 : {
598 0 : MakeUnique();
599 0 : mpImplFont->meOverline = eOverline;
600 : }
601 65778 : }
602 :
603 : // -----------------------------------------------------------------------
604 :
605 66178 : void Font::SetStrikeout( FontStrikeout eStrikeout )
606 : {
607 : DBG_CHKTHIS( Font, NULL );
608 :
609 66178 : if( mpImplFont->meStrikeout != eStrikeout )
610 : {
611 38 : MakeUnique();
612 38 : mpImplFont->meStrikeout = eStrikeout;
613 : }
614 66178 : }
615 :
616 : // -----------------------------------------------------------------------
617 :
618 62925 : void Font::SetRelief( FontRelief eRelief )
619 : {
620 : DBG_CHKTHIS( Font, NULL );
621 :
622 62925 : if( mpImplFont->meRelief != eRelief )
623 : {
624 0 : MakeUnique();
625 0 : mpImplFont->meRelief = eRelief;
626 : }
627 62925 : }
628 :
629 : // -----------------------------------------------------------------------
630 :
631 65519 : void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark )
632 : {
633 : DBG_CHKTHIS( Font, NULL );
634 :
635 65519 : if( mpImplFont->meEmphasisMark != eEmphasisMark )
636 : {
637 0 : MakeUnique();
638 0 : mpImplFont->meEmphasisMark = eEmphasisMark;
639 : }
640 65519 : }
641 :
642 : // -----------------------------------------------------------------------
643 :
644 65765 : void Font::SetWordLineMode( sal_Bool bWordLine )
645 : {
646 : DBG_CHKTHIS( Font, NULL );
647 :
648 65765 : if( mpImplFont->mbWordLine != bWordLine )
649 : {
650 0 : MakeUnique();
651 0 : mpImplFont->mbWordLine = bWordLine;
652 : }
653 65765 : }
654 :
655 : // -----------------------------------------------------------------------
656 :
657 375804 : Font& Font::operator=( const Font& rFont )
658 : {
659 : DBG_CHKTHIS( Font, NULL );
660 : DBG_CHKOBJ( &rFont, Font, NULL );
661 : DBG_ASSERT( rFont.mpImplFont->mnRefCount < 0xFFFE, "Font: RefCount overflow" );
662 :
663 : // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
664 : // RefCount == 0 fuer statische Objekte
665 375804 : if ( rFont.mpImplFont->mnRefCount )
666 375111 : rFont.mpImplFont->mnRefCount++;
667 :
668 : // Wenn es keine statischen ImplDaten sind, dann loeschen, wenn es
669 : // die letzte Referenz ist, sonst Referenzcounter decrementieren
670 375804 : if ( mpImplFont->mnRefCount )
671 : {
672 230795 : if ( mpImplFont->mnRefCount == 1 )
673 88755 : delete mpImplFont;
674 : else
675 142040 : mpImplFont->mnRefCount--;
676 : }
677 :
678 375804 : mpImplFont = rFont.mpImplFont;
679 :
680 375804 : return *this;
681 : }
682 :
683 : // -----------------------------------------------------------------------
684 :
685 113004 : sal_Bool Font::operator==( const Font& rFont ) const
686 : {
687 : DBG_CHKTHIS( Font, NULL );
688 : DBG_CHKOBJ( &rFont, Font, NULL );
689 :
690 113004 : if( mpImplFont == rFont.mpImplFont )
691 45254 : return sal_True;
692 67750 : if( *mpImplFont == *rFont.mpImplFont )
693 47599 : return sal_True;
694 :
695 20151 : return sal_False;
696 : }
697 :
698 : // -----------------------------------------------------------------------
699 :
700 24 : void Font::Merge( const Font& rFont )
701 : {
702 24 : if ( rFont.GetName().Len() )
703 : {
704 24 : SetName( rFont.GetName() );
705 24 : SetStyleName( rFont.GetStyleName() );
706 24 : SetCharSet( GetCharSet() );
707 24 : SetLanguage( rFont.GetLanguage() );
708 24 : SetCJKContextLanguage( rFont.GetCJKContextLanguage() );
709 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
710 24 : SetFamily( rFont.mpImplFont->meFamily );
711 24 : SetPitch( rFont.mpImplFont->mePitch );
712 : }
713 :
714 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
715 24 : if ( rFont.mpImplFont->meWeight != WEIGHT_DONTKNOW )
716 24 : SetWeight( rFont.GetWeight() );
717 24 : if ( rFont.mpImplFont->meItalic != ITALIC_DONTKNOW )
718 24 : SetItalic( rFont.GetItalic() );
719 24 : if ( rFont.mpImplFont->meWidthType != WIDTH_DONTKNOW )
720 0 : SetWidthType( rFont.GetWidthType() );
721 :
722 :
723 24 : if ( rFont.GetSize().Height() )
724 24 : SetSize( rFont.GetSize() );
725 24 : if ( rFont.GetUnderline() != UNDERLINE_DONTKNOW )
726 : {
727 24 : SetUnderline( rFont.GetUnderline() );
728 24 : SetWordLineMode( rFont.IsWordLineMode() );
729 : }
730 24 : if ( rFont.GetOverline() != UNDERLINE_DONTKNOW )
731 : {
732 24 : SetOverline( rFont.GetOverline() );
733 24 : SetWordLineMode( rFont.IsWordLineMode() );
734 : }
735 24 : if ( rFont.GetStrikeout() != STRIKEOUT_DONTKNOW )
736 : {
737 24 : SetStrikeout( rFont.GetStrikeout() );
738 24 : SetWordLineMode( rFont.IsWordLineMode() );
739 : }
740 :
741 : // Defaults?
742 24 : SetOrientation( rFont.GetOrientation() );
743 24 : SetVertical( rFont.IsVertical() );
744 24 : SetEmphasisMark( rFont.GetEmphasisMark() );
745 24 : SetKerning( rFont.IsKerning() );
746 24 : SetOutline( rFont.IsOutline() );
747 24 : SetShadow( rFont.IsShadow() );
748 24 : SetRelief( rFont.GetRelief() );
749 24 : }
750 :
751 63814 : void Font::GetFontAttributes( ImplFontAttributes& rAttrs ) const
752 : {
753 : // #i56788# Use members directly, don't risc config access.
754 63814 : rAttrs.maName = mpImplFont->maFamilyName;
755 63814 : rAttrs.maStyleName = mpImplFont->maStyleName;
756 63814 : rAttrs.meFamily = mpImplFont->meFamily;
757 63814 : rAttrs.mePitch = mpImplFont->mePitch;
758 63814 : rAttrs.meItalic = mpImplFont->meItalic;
759 63814 : rAttrs.meWeight = mpImplFont->meWeight;
760 63814 : rAttrs.meWidthType = WIDTH_DONTKNOW;
761 63814 : rAttrs.mbSymbolFlag= (mpImplFont->meCharSet == RTL_TEXTENCODING_SYMBOL);
762 63814 : }
763 :
764 :
765 : // -----------------------------------------------------------------------
766 :
767 21985 : SvStream& operator>>( SvStream& rIStm, Impl_Font& rImpl_Font )
768 : {
769 21985 : VersionCompat aCompat( rIStm, STREAM_READ );
770 : sal_uInt16 nTmp16;
771 : sal_Bool bTmp;
772 : sal_uInt8 nTmp8;
773 :
774 21985 : rImpl_Font.maFamilyName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
775 21985 : rImpl_Font.maStyleName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
776 21985 : rIStm >> rImpl_Font.maSize;
777 :
778 21985 : rIStm >> nTmp16; rImpl_Font.meCharSet = (rtl_TextEncoding) nTmp16;
779 21985 : rIStm >> nTmp16; rImpl_Font.meFamily = (FontFamily) nTmp16;
780 21985 : rIStm >> nTmp16; rImpl_Font.mePitch = (FontPitch) nTmp16;
781 21985 : rIStm >> nTmp16; rImpl_Font.meWeight = (FontWeight) nTmp16;
782 21985 : rIStm >> nTmp16; rImpl_Font.meUnderline = (FontUnderline) nTmp16;
783 21985 : rIStm >> nTmp16; rImpl_Font.meStrikeout = (FontStrikeout) nTmp16;
784 21985 : rIStm >> nTmp16; rImpl_Font.meItalic = (FontItalic) nTmp16;
785 21985 : rIStm >> nTmp16; rImpl_Font.meLanguage = (LanguageType) nTmp16;
786 21985 : rIStm >> nTmp16; rImpl_Font.meWidthType = (FontWidth) nTmp16;
787 :
788 21985 : rIStm >> rImpl_Font.mnOrientation;
789 :
790 21985 : rIStm >> bTmp; rImpl_Font.mbWordLine = bTmp;
791 21985 : rIStm >> bTmp; rImpl_Font.mbOutline = bTmp;
792 21985 : rIStm >> bTmp; rImpl_Font.mbShadow = bTmp;
793 21985 : rIStm >> nTmp8; rImpl_Font.mnKerning = nTmp8;
794 :
795 21985 : if( aCompat.GetVersion() >= 2 )
796 : {
797 21985 : rIStm >> nTmp8; rImpl_Font.meRelief = (FontRelief)nTmp8;
798 21985 : rIStm >> nTmp16; rImpl_Font.meCJKLanguage = (LanguageType)nTmp16;
799 21985 : rIStm >> bTmp; rImpl_Font.mbVertical = bTmp;
800 21985 : rIStm >> nTmp16; rImpl_Font.meEmphasisMark = (FontEmphasisMark)nTmp16;
801 : }
802 21985 : if( aCompat.GetVersion() >= 3 )
803 : {
804 21985 : rIStm >> nTmp16; rImpl_Font.meOverline = (FontUnderline) nTmp16;
805 : }
806 : // Relief
807 : // CJKContextLanguage
808 :
809 21985 : return rIStm;
810 : }
811 :
812 : // -----------------------------------------------------------------------
813 :
814 23394 : SvStream& operator<<( SvStream& rOStm, const Impl_Font& rImpl_Font )
815 : {
816 23394 : VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
817 23394 : rOStm.WriteUniOrByteString( rImpl_Font.maFamilyName, rOStm.GetStreamCharSet() );
818 23394 : rOStm.WriteUniOrByteString( rImpl_Font.maStyleName, rOStm.GetStreamCharSet() );
819 23394 : rOStm << rImpl_Font.maSize;
820 :
821 23394 : rOStm << (sal_uInt16) GetStoreCharSet( rImpl_Font.meCharSet );
822 23394 : rOStm << (sal_uInt16) rImpl_Font.meFamily;
823 23394 : rOStm << (sal_uInt16) rImpl_Font.mePitch;
824 23394 : rOStm << (sal_uInt16) rImpl_Font.meWeight;
825 23394 : rOStm << (sal_uInt16) rImpl_Font.meUnderline;
826 23394 : rOStm << (sal_uInt16) rImpl_Font.meStrikeout;
827 23394 : rOStm << (sal_uInt16) rImpl_Font.meItalic;
828 23394 : rOStm << (sal_uInt16) rImpl_Font.meLanguage;
829 23394 : rOStm << (sal_uInt16) rImpl_Font.meWidthType;
830 :
831 23394 : rOStm << rImpl_Font.mnOrientation;
832 :
833 23394 : rOStm << (sal_Bool) rImpl_Font.mbWordLine;
834 23394 : rOStm << (sal_Bool) rImpl_Font.mbOutline;
835 23394 : rOStm << (sal_Bool) rImpl_Font.mbShadow;
836 23394 : rOStm << (sal_uInt8) rImpl_Font.mnKerning;
837 :
838 : // new in version 2
839 23394 : rOStm << (sal_uInt8) rImpl_Font.meRelief;
840 23394 : rOStm << (sal_uInt16) rImpl_Font.meCJKLanguage;
841 23394 : rOStm << (sal_Bool) rImpl_Font.mbVertical;
842 23394 : rOStm << (sal_uInt16) rImpl_Font.meEmphasisMark;
843 :
844 : // new in version 3
845 23394 : rOStm << (sal_uInt16) rImpl_Font.meOverline;
846 :
847 23394 : return rOStm;
848 : }
849 :
850 : // -----------------------------------------------------------------------
851 :
852 21985 : SvStream& operator>>( SvStream& rIStm, Font& rFont )
853 : {
854 21985 : rFont.MakeUnique();
855 21985 : return( rIStm >> *rFont.mpImplFont );
856 : }
857 :
858 : // -----------------------------------------------------------------------
859 :
860 23394 : SvStream& operator<<( SvStream& rOStm, const Font& rFont )
861 : {
862 23394 : return( rOStm << *rFont.mpImplFont );
863 : }
864 :
865 : // -----------------------------------------------------------------------
866 : namespace
867 : {
868 0 : bool identifyTrueTypeFont( const void* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
869 : {
870 0 : bool bResult = false;
871 0 : TrueTypeFont* pTTF = NULL;
872 0 : if( OpenTTFontBuffer( const_cast<void*>(i_pBuffer), i_nSize, 0, &pTTF ) == SF_OK )
873 : {
874 : TTGlobalFontInfo aInfo;
875 0 : GetTTGlobalFontInfo( pTTF, &aInfo );
876 : // most important: the family name
877 0 : if( aInfo.ufamily )
878 0 : o_rResult.SetName( aInfo.ufamily );
879 0 : else if( aInfo.family )
880 0 : o_rResult.SetName( rtl::OStringToOUString( aInfo.family, RTL_TEXTENCODING_ASCII_US ) );
881 : // set weight
882 0 : if( aInfo.weight )
883 : {
884 0 : if( aInfo.weight < FW_EXTRALIGHT )
885 0 : o_rResult.SetWeight( WEIGHT_THIN );
886 0 : else if( aInfo.weight < FW_LIGHT )
887 0 : o_rResult.SetWeight( WEIGHT_ULTRALIGHT );
888 0 : else if( aInfo.weight < FW_NORMAL )
889 0 : o_rResult.SetWeight( WEIGHT_LIGHT );
890 0 : else if( aInfo.weight < FW_MEDIUM )
891 0 : o_rResult.SetWeight( WEIGHT_NORMAL );
892 0 : else if( aInfo.weight < FW_SEMIBOLD )
893 0 : o_rResult.SetWeight( WEIGHT_MEDIUM );
894 0 : else if( aInfo.weight < FW_BOLD )
895 0 : o_rResult.SetWeight( WEIGHT_SEMIBOLD );
896 0 : else if( aInfo.weight < FW_EXTRABOLD )
897 0 : o_rResult.SetWeight( WEIGHT_BOLD );
898 0 : else if( aInfo.weight < FW_BLACK )
899 0 : o_rResult.SetWeight( WEIGHT_ULTRABOLD );
900 : else
901 0 : o_rResult.SetWeight( WEIGHT_BLACK );
902 : }
903 : else
904 0 : o_rResult.SetWeight( (aInfo.macStyle & 1) ? WEIGHT_BOLD : WEIGHT_NORMAL );
905 : // set width
906 0 : if( aInfo.width )
907 : {
908 0 : if( aInfo.width == FWIDTH_ULTRA_CONDENSED )
909 0 : o_rResult.SetWidth( WIDTH_ULTRA_CONDENSED );
910 0 : else if( aInfo.width == FWIDTH_EXTRA_CONDENSED )
911 0 : o_rResult.SetWidth( WIDTH_EXTRA_CONDENSED );
912 0 : else if( aInfo.width == FWIDTH_CONDENSED )
913 0 : o_rResult.SetWidth( WIDTH_CONDENSED );
914 0 : else if( aInfo.width == FWIDTH_SEMI_CONDENSED )
915 0 : o_rResult.SetWidth( WIDTH_SEMI_CONDENSED );
916 0 : else if( aInfo.width == FWIDTH_NORMAL )
917 0 : o_rResult.SetWidth( WIDTH_NORMAL );
918 0 : else if( aInfo.width == FWIDTH_SEMI_EXPANDED )
919 0 : o_rResult.SetWidth( WIDTH_SEMI_EXPANDED );
920 0 : else if( aInfo.width == FWIDTH_EXPANDED )
921 0 : o_rResult.SetWidth( WIDTH_EXPANDED );
922 0 : else if( aInfo.width == FWIDTH_EXTRA_EXPANDED )
923 0 : o_rResult.SetWidth( WIDTH_EXTRA_EXPANDED );
924 0 : else if( aInfo.width >= FWIDTH_ULTRA_EXPANDED )
925 0 : o_rResult.SetWidth( WIDTH_ULTRA_EXPANDED );
926 : }
927 : // set italic
928 0 : o_rResult.SetItalic( (aInfo.italicAngle != 0) ? ITALIC_NORMAL : ITALIC_NONE );
929 :
930 : // set pitch
931 0 : o_rResult.SetPitch( (aInfo.pitch == 0) ? PITCH_VARIABLE : PITCH_FIXED );
932 :
933 : // set style name
934 0 : if( aInfo.usubfamily )
935 0 : o_rResult.SetStyleName( rtl::OUString( aInfo.usubfamily ) );
936 0 : else if( aInfo.subfamily )
937 0 : o_rResult.SetStyleName( rtl::OUString::createFromAscii( aInfo.subfamily ) );
938 :
939 : // cleanup
940 0 : CloseTTFont( pTTF );
941 : // success
942 0 : bResult = true;
943 : }
944 0 : return bResult;
945 : }
946 :
947 : struct WeightSearchEntry
948 : {
949 : const char* string;
950 : int string_len;
951 : FontWeight weight;
952 :
953 0 : bool operator<( const WeightSearchEntry& rRight ) const
954 : {
955 0 : return rtl_str_compareIgnoreAsciiCase_WithLength( string, string_len, rRight.string, rRight.string_len ) < 0;
956 : }
957 : }
958 : weight_table[] =
959 : {
960 : { "black", 5, WEIGHT_BLACK },
961 : { "bold", 4, WEIGHT_BOLD },
962 : { "book", 4, WEIGHT_LIGHT },
963 : { "demi", 4, WEIGHT_SEMIBOLD },
964 : { "heavy", 5, WEIGHT_BLACK },
965 : { "light", 5, WEIGHT_LIGHT },
966 : { "medium", 6, WEIGHT_MEDIUM },
967 : { "regular", 7, WEIGHT_NORMAL },
968 : { "super", 5, WEIGHT_ULTRABOLD },
969 : { "thin", 4, WEIGHT_THIN }
970 : };
971 :
972 0 : bool identifyType1Font( const char* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
973 : {
974 0 : bool bResult = false;
975 : // might be a type1, find eexec
976 0 : const char* pStream = i_pBuffer;
977 0 : const char* pExec = "eexec";
978 0 : const char* pExecPos = std::search( pStream, pStream+i_nSize, pExec, pExec+5 );
979 0 : if( pExecPos != pStream+i_nSize)
980 : {
981 : // find /FamilyName entry
982 : static const char* pFam = "/FamilyName";
983 0 : const char* pFamPos = std::search( pStream, pExecPos, pFam, pFam+11 );
984 0 : if( pFamPos != pExecPos )
985 : {
986 : // extract the string value behind /FamilyName
987 0 : const char* pOpen = pFamPos+11;
988 0 : while( pOpen < pExecPos && *pOpen != '(' )
989 0 : pOpen++;
990 0 : const char* pClose = pOpen;
991 0 : while( pClose < pExecPos && *pClose != ')' )
992 0 : pClose++;
993 0 : if( pClose - pOpen > 1 )
994 : {
995 0 : o_rResult.SetName( rtl::OStringToOUString( rtl::OString( pOpen+1, pClose-pOpen-1 ), RTL_TEXTENCODING_ASCII_US ) );
996 : }
997 : }
998 :
999 : // parse /ItalicAngle
1000 : static const char* pItalic = "/ItalicAngle";
1001 0 : const char* pItalicPos = std::search( pStream, pExecPos, pItalic, pItalic+12 );
1002 0 : if( pItalicPos != pExecPos )
1003 : {
1004 0 : sal_Int32 nItalic = rtl_str_toInt32( pItalicPos+12, 10 );
1005 0 : o_rResult.SetItalic( (nItalic != 0) ? ITALIC_NORMAL : ITALIC_NONE );
1006 : }
1007 :
1008 : // parse /Weight
1009 : static const char* pWeight = "/Weight";
1010 0 : const char* pWeightPos = std::search( pStream, pExecPos, pWeight, pWeight+7 );
1011 0 : if( pWeightPos != pExecPos )
1012 : {
1013 : // extract the string value behind /Weight
1014 0 : const char* pOpen = pWeightPos+7;
1015 0 : while( pOpen < pExecPos && *pOpen != '(' )
1016 0 : pOpen++;
1017 0 : const char* pClose = pOpen;
1018 0 : while( pClose < pExecPos && *pClose != ')' )
1019 0 : pClose++;
1020 0 : if( pClose - pOpen > 1 )
1021 : {
1022 : WeightSearchEntry aEnt;
1023 0 : aEnt.string = pOpen+1;
1024 0 : aEnt.string_len = (pClose-pOpen)-1;
1025 0 : aEnt.weight = WEIGHT_NORMAL;
1026 0 : const int nEnt = SAL_N_ELEMENTS( weight_table );
1027 0 : WeightSearchEntry* pFound = std::lower_bound( weight_table, weight_table+nEnt, aEnt );
1028 0 : if( pFound != (weight_table+nEnt) )
1029 0 : o_rResult.SetWeight( pFound->weight );
1030 : }
1031 : }
1032 :
1033 : // parse isFixedPitch
1034 : static const char* pFixed = "/isFixedPitch";
1035 0 : const char* pFixedPos = std::search( pStream, pExecPos, pFixed, pFixed+13 );
1036 0 : if( pFixedPos != pExecPos )
1037 : {
1038 : // skip whitespace
1039 0 : while( pFixedPos < pExecPos-4 &&
1040 : ( *pFixedPos == ' ' ||
1041 : *pFixedPos == '\t' ||
1042 : *pFixedPos == '\r' ||
1043 : *pFixedPos == '\n' ) )
1044 : {
1045 0 : pFixedPos++;
1046 : }
1047 : // find "true" value
1048 0 : if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos, 4, "true", 4 ) == 0 )
1049 0 : o_rResult.SetPitch( PITCH_FIXED );
1050 : else
1051 0 : o_rResult.SetPitch( PITCH_VARIABLE );
1052 : }
1053 : }
1054 0 : return bResult;
1055 : }
1056 : }
1057 :
1058 0 : Font Font::identifyFont( const void* i_pBuffer, sal_uInt32 i_nSize )
1059 : {
1060 0 : Font aResult;
1061 0 : if( ! identifyTrueTypeFont( i_pBuffer, i_nSize, aResult ) )
1062 : {
1063 0 : const char* pStream = reinterpret_cast<const char*>(i_pBuffer);
1064 0 : if( pStream && i_nSize > 100 &&
1065 0 : *pStream == '%' && pStream[1] == '!' )
1066 : {
1067 0 : identifyType1Font( pStream, i_nSize, aResult );
1068 : }
1069 : }
1070 :
1071 0 : return aResult;
1072 : }
1073 :
1074 : // the inlines from the font.hxx header are now instantiated for pImpl-ification
1075 : // TODO: reformat
1076 236113 : const Color& Font::GetColor() const { return mpImplFont->maColor; }
1077 22518 : const Color& Font::GetFillColor() const { return mpImplFont->maFillColor; }
1078 42782 : sal_Bool Font::IsTransparent() const { return mpImplFont->mbTransparent; }
1079 96900 : FontAlign Font::GetAlign() const { return mpImplFont->meAlign; }
1080 270730 : const String& Font::GetName() const { return mpImplFont->maFamilyName; }
1081 1088 : const String& Font::GetStyleName() const { return mpImplFont->maStyleName; }
1082 262011 : const Size& Font::GetSize() const { return mpImplFont->maSize; }
1083 15978 : void Font::SetHeight( long nHeight ) { SetSize( Size( mpImplFont->maSize.Width(), nHeight ) ); }
1084 69011 : long Font::GetHeight() const { return mpImplFont->maSize.Height(); }
1085 0 : void Font::SetWidth( long nWidth ) { SetSize( Size( nWidth, mpImplFont->maSize.Height() ) ); }
1086 64 : long Font::GetWidth() const { return mpImplFont->maSize.Width(); }
1087 85967 : rtl_TextEncoding Font::GetCharSet() const { return mpImplFont->meCharSet; }
1088 186124 : LanguageType Font::GetLanguage() const { return mpImplFont->meLanguage; }
1089 24 : LanguageType Font::GetCJKContextLanguage() const { return mpImplFont->meCJKLanguage; }
1090 66769 : short Font::GetOrientation() const { return mpImplFont->mnOrientation; }
1091 116107 : sal_Bool Font::IsVertical() const { return mpImplFont->mbVertical; }
1092 227914 : FontKerning Font::GetKerning() const { return mpImplFont->mnKerning; }
1093 8055 : FontPitch Font::GetPitch() const { return mpImplFont->GetPitch(); }
1094 42719 : FontWeight Font::GetWeight() const { return mpImplFont->GetWeight(); }
1095 0 : FontWidth Font::GetWidthType() const { return mpImplFont->GetWidthType(); }
1096 193175 : FontItalic Font::GetItalic() const { return mpImplFont->GetItalic(); }
1097 7845 : FontFamily Font::GetFamily() const { return mpImplFont->GetFamily(); }
1098 48578 : sal_Bool Font::IsOutline() const { return mpImplFont->mbOutline; }
1099 48580 : sal_Bool Font::IsShadow() const { return mpImplFont->mbShadow; }
1100 49424 : FontRelief Font::GetRelief() const { return mpImplFont->meRelief; }
1101 57838 : FontUnderline Font::GetUnderline() const { return mpImplFont->meUnderline; }
1102 53958 : FontUnderline Font::GetOverline() const { return mpImplFont->meOverline; }
1103 54756 : FontStrikeout Font::GetStrikeout() const { return mpImplFont->meStrikeout; }
1104 55850 : FontEmphasisMark Font::GetEmphasisMark() const { return mpImplFont->meEmphasisMark; }
1105 7020 : sal_Bool Font::IsWordLineMode() const { return mpImplFont->mbWordLine; }
1106 171894 : sal_Bool Font::IsSameInstance( const Font& rFont ) const { return (mpImplFont == rFont.mpImplFont); }
1107 :
1108 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|