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 10875 : Impl_Font::Impl_Font() :
46 : maColor( COL_TRANSPARENT ),
47 10875 : maFillColor( COL_TRANSPARENT )
48 : {
49 10875 : mnRefCount = 1;
50 10875 : meCharSet = RTL_TEXTENCODING_DONTKNOW;
51 10875 : meLanguage = LANGUAGE_DONTKNOW;
52 10875 : meCJKLanguage = LANGUAGE_DONTKNOW;
53 10875 : meFamily = FAMILY_DONTKNOW;
54 10875 : mePitch = PITCH_DONTKNOW;
55 10875 : meAlign = ALIGN_TOP;
56 10875 : meWeight = WEIGHT_DONTKNOW;
57 10875 : meWidthType = WIDTH_DONTKNOW;
58 10875 : meItalic = ITALIC_NONE;
59 10875 : meUnderline = UNDERLINE_NONE;
60 10875 : meOverline = UNDERLINE_NONE;
61 10875 : meStrikeout = STRIKEOUT_NONE;
62 10875 : meRelief = RELIEF_NONE;
63 10875 : meEmphasisMark = EMPHASISMARK_NONE;
64 10875 : mnOrientation = 0;
65 10875 : mnKerning = 0;
66 10875 : mbWordLine = false;
67 10875 : mbOutline = false;
68 10875 : mbShadow = false;
69 10875 : mbVertical = false;
70 10875 : mbTransparent = true;
71 10875 : mbConfigLookup = false;
72 10875 : }
73 :
74 : // -----------------------------------------------------------------------
75 :
76 591016 : 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 591016 : maFillColor( rImplFont.maFillColor )
82 : {
83 591016 : mnRefCount = 1;
84 591016 : meCharSet = rImplFont.meCharSet;
85 591016 : meLanguage = rImplFont.meLanguage;
86 591016 : meCJKLanguage = rImplFont.meCJKLanguage;
87 591016 : meFamily = rImplFont.meFamily;
88 591016 : mePitch = rImplFont.mePitch;
89 591016 : meAlign = rImplFont.meAlign;
90 591016 : meWeight = rImplFont.meWeight;
91 591016 : meWidthType = rImplFont.meWidthType;
92 591016 : meItalic = rImplFont.meItalic;
93 591016 : meUnderline = rImplFont.meUnderline;
94 591016 : meOverline = rImplFont.meOverline;
95 591016 : meStrikeout = rImplFont.meStrikeout;
96 591016 : meRelief = rImplFont.meRelief;
97 591016 : meEmphasisMark = rImplFont.meEmphasisMark;
98 591016 : mnOrientation = rImplFont.mnOrientation;
99 591016 : mnKerning = rImplFont.mnKerning;
100 591016 : mbWordLine = rImplFont.mbWordLine;
101 591016 : mbOutline = rImplFont.mbOutline;
102 591016 : mbShadow = rImplFont.mbShadow;
103 591016 : mbVertical = rImplFont.mbVertical;
104 591016 : mbTransparent = rImplFont.mbTransparent;
105 591016 : mbConfigLookup = rImplFont.mbConfigLookup;
106 591016 : }
107 :
108 : // -----------------------------------------------------------------------
109 :
110 140351 : bool Impl_Font::operator==( const Impl_Font& rOther ) const
111 : {
112 : // equality tests split up for easier debugging
113 140351 : if( (meWeight != rOther.meWeight)
114 : || (meItalic != rOther.meItalic)
115 : || (meFamily != rOther.meFamily)
116 : || (mePitch != rOther.mePitch) )
117 24744 : return false;
118 :
119 115607 : if( (meCharSet != rOther.meCharSet)
120 : || (meLanguage != rOther.meLanguage)
121 : || (meCJKLanguage != rOther.meCJKLanguage)
122 : || (meAlign != rOther.meAlign) )
123 11692 : return false;
124 :
125 103915 : if( (maSize != rOther.maSize)
126 : || (mnOrientation != rOther.mnOrientation)
127 : || (mbVertical != rOther.mbVertical) )
128 6836 : return false;
129 :
130 194052 : if( (maFamilyName != rOther.maFamilyName)
131 96973 : || (maStyleName != rOther.maStyleName) )
132 106 : return false;
133 :
134 193844 : if( (maColor != rOther.maColor)
135 96871 : || (maFillColor != rOther.maFillColor) )
136 102 : return false;
137 :
138 96871 : 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 226 : return false;
149 :
150 96645 : return true;
151 : }
152 :
153 : // -----------------------------------------------------------------------
154 :
155 26424 : void Impl_Font::AskConfig()
156 : {
157 26424 : if( mbConfigLookup )
158 26424 : return;
159 :
160 9718 : mbConfigLookup = true;
161 :
162 : // prepare the FontSubst configuration lookup
163 9718 : const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
164 :
165 9718 : String aShortName;
166 9718 : String aFamilyName;
167 9718 : sal_uLong nType = 0;
168 9718 : FontWeight eWeight = WEIGHT_DONTKNOW;
169 9718 : FontWidth eWidthType = WIDTH_DONTKNOW;
170 9718 : String aMapName = maFamilyName;
171 9718 : GetEnglishSearchFontName( aMapName );
172 : utl::FontSubstConfiguration::getMapName( aMapName,
173 9718 : aShortName, aFamilyName, eWeight, eWidthType, nType );
174 :
175 : // lookup the font name in the configuration
176 9718 : const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
177 :
178 : // if the direct lookup failed try again with an alias name
179 9718 : if ( !pFontAttr && (aShortName != aMapName) )
180 518 : pFontAttr = rFontSubst.getSubstInfo( aShortName );
181 :
182 9718 : if( pFontAttr )
183 : {
184 : // the font was found in the configuration
185 6537 : if( meFamily == FAMILY_DONTKNOW )
186 : {
187 5523 : if ( pFontAttr->Type & IMPL_FONT_ATTR_SERIF )
188 2100 : meFamily = FAMILY_ROMAN;
189 3423 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_SANSSERIF )
190 538 : meFamily = FAMILY_SWISS;
191 2885 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_TYPEWRITER )
192 10 : meFamily = FAMILY_MODERN;
193 2875 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_ITALIC )
194 0 : meFamily = FAMILY_SCRIPT;
195 2875 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_DECORATIVE )
196 0 : meFamily = FAMILY_DECORATIVE;
197 : }
198 :
199 6537 : if( mePitch == PITCH_DONTKNOW )
200 : {
201 6537 : if ( pFontAttr->Type & IMPL_FONT_ATTR_FIXED )
202 10 : mePitch = PITCH_FIXED;
203 : }
204 : }
205 :
206 : // if some attributes are still unknown then use the FontSubst magic
207 9718 : if( meFamily == FAMILY_DONTKNOW )
208 : {
209 6044 : if( nType & IMPL_FONT_ATTR_SERIF )
210 0 : meFamily = FAMILY_ROMAN;
211 6044 : else if( nType & IMPL_FONT_ATTR_SANSSERIF )
212 0 : meFamily = FAMILY_SWISS;
213 6044 : else if( nType & IMPL_FONT_ATTR_TYPEWRITER )
214 0 : meFamily = FAMILY_MODERN;
215 6044 : else if( nType & IMPL_FONT_ATTR_ITALIC )
216 0 : meFamily = FAMILY_SCRIPT;
217 6044 : else if( nType & IMPL_FONT_ATTR_DECORATIVE )
218 0 : meFamily = FAMILY_DECORATIVE;
219 : }
220 :
221 9718 : if( meWeight == WEIGHT_DONTKNOW )
222 8140 : meWeight = eWeight;
223 9718 : if( meWidthType == WIDTH_DONTKNOW )
224 9718 : meWidthType = eWidthType;
225 : }
226 :
227 : // =======================================================================
228 :
229 2151368 : void Font::MakeUnique()
230 : {
231 : // create a copy if others still reference it
232 2151368 : if ( mpImplFont->mnRefCount != 1 )
233 : {
234 591016 : if ( mpImplFont->mnRefCount )
235 354548 : mpImplFont->mnRefCount--;
236 591016 : mpImplFont = new Impl_Font( *mpImplFont );
237 : }
238 2151368 : }
239 :
240 : // -----------------------------------------------------------------------
241 :
242 568763 : Font::Font()
243 : {
244 : DBG_CTOR( Font, NULL );
245 :
246 568763 : static Impl_Font aStaticImplFont;
247 : // RefCount is zero for static objects
248 568763 : aStaticImplFont.mnRefCount = 0;
249 568763 : mpImplFont = &aStaticImplFont;
250 568763 : }
251 :
252 : // -----------------------------------------------------------------------
253 :
254 893822 : 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 893822 : mpImplFont = rFont.mpImplFont;
261 : // do not count static objects (where RefCount is zero)
262 893822 : if ( mpImplFont->mnRefCount )
263 881505 : mpImplFont->mnRefCount++;
264 893822 : }
265 :
266 : // -----------------------------------------------------------------------
267 :
268 10231 : Font::Font( const String& rFamilyName, const Size& rSize )
269 : {
270 : DBG_CTOR( Font, NULL );
271 :
272 10231 : mpImplFont = new Impl_Font;
273 10231 : mpImplFont->maFamilyName= rFamilyName;
274 10231 : mpImplFont->maSize = rSize;
275 10231 : }
276 :
277 : // -----------------------------------------------------------------------
278 :
279 464 : Font::Font( const String& rFamilyName, const String& rStyleName, const Size& rSize )
280 : {
281 : DBG_CTOR( Font, NULL );
282 :
283 464 : mpImplFont = new Impl_Font;
284 464 : mpImplFont->maFamilyName= rFamilyName;
285 464 : mpImplFont->maStyleName = rStyleName;
286 464 : mpImplFont->maSize = rSize;
287 464 : }
288 :
289 : // -----------------------------------------------------------------------
290 :
291 94 : Font::Font( FontFamily eFamily, const Size& rSize )
292 : {
293 : DBG_CTOR( Font, NULL );
294 :
295 94 : mpImplFont = new Impl_Font;
296 94 : mpImplFont->meFamily = eFamily;
297 94 : mpImplFont->maSize = rSize;
298 94 : }
299 :
300 : // -----------------------------------------------------------------------
301 :
302 1371882 : 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 1371882 : if ( mpImplFont->mnRefCount )
309 : {
310 1352723 : if ( mpImplFont->mnRefCount == 1 )
311 348433 : delete mpImplFont;
312 : else
313 1004290 : mpImplFont->mnRefCount--;
314 : }
315 1371882 : }
316 :
317 : // -----------------------------------------------------------------------
318 :
319 191872 : void Font::SetColor( const Color& rColor )
320 : {
321 : DBG_CHKTHIS( Font, NULL );
322 :
323 191872 : if( mpImplFont->maColor != rColor )
324 : {
325 29776 : MakeUnique();
326 29776 : mpImplFont->maColor = rColor;
327 : }
328 191872 : }
329 :
330 : // -----------------------------------------------------------------------
331 :
332 1524 : void Font::SetFillColor( const Color& rColor )
333 : {
334 : DBG_CHKTHIS( Font, NULL );
335 :
336 1524 : MakeUnique();
337 1524 : mpImplFont->maFillColor = rColor;
338 1524 : if ( rColor.GetTransparency() )
339 1210 : mpImplFont->mbTransparent = true;
340 1524 : }
341 :
342 : // -----------------------------------------------------------------------
343 :
344 208292 : void Font::SetTransparent( sal_Bool bTransparent )
345 : {
346 : DBG_CHKTHIS( Font, NULL );
347 :
348 208292 : if( mpImplFont->mbTransparent != bTransparent )
349 : {
350 152 : MakeUnique();
351 152 : mpImplFont->mbTransparent = bTransparent;
352 : }
353 208292 : }
354 :
355 : // -----------------------------------------------------------------------
356 :
357 238496 : void Font::SetAlign( FontAlign eAlign )
358 : {
359 : DBG_CHKTHIS( Font, NULL );
360 :
361 238496 : if( mpImplFont->meAlign != eAlign )
362 : {
363 64809 : MakeUnique();
364 64809 : mpImplFont->meAlign = eAlign;
365 : }
366 238496 : }
367 :
368 : // -----------------------------------------------------------------------
369 :
370 422039 : void Font::SetName( const rtl::OUString& rFamilyName )
371 : {
372 : DBG_CHKTHIS( Font, NULL );
373 :
374 422039 : MakeUnique();
375 422039 : mpImplFont->maFamilyName = rFamilyName;
376 422039 : }
377 :
378 : // -----------------------------------------------------------------------
379 :
380 209431 : void Font::SetStyleName( const String& rStyleName )
381 : {
382 : DBG_CHKTHIS( Font, NULL );
383 :
384 209431 : MakeUnique();
385 209431 : mpImplFont->maStyleName = rStyleName;
386 209431 : }
387 :
388 : // -----------------------------------------------------------------------
389 :
390 375954 : void Font::SetSize( const Size& rSize )
391 : {
392 : DBG_CHKTHIS( Font, NULL );
393 :
394 375954 : if( mpImplFont->maSize != rSize )
395 : {
396 249557 : MakeUnique();
397 249557 : mpImplFont->maSize = rSize;
398 : }
399 375954 : }
400 :
401 : // -----------------------------------------------------------------------
402 :
403 389343 : void Font::SetFamily( FontFamily eFamily )
404 : {
405 : DBG_CHKTHIS( Font, NULL );
406 :
407 389343 : if( mpImplFont->meFamily != eFamily )
408 : {
409 142697 : MakeUnique();
410 142697 : mpImplFont->meFamily = eFamily;
411 : }
412 389343 : }
413 :
414 : // -----------------------------------------------------------------------
415 :
416 391209 : void Font::SetCharSet( CharSet eCharSet )
417 : {
418 : DBG_CHKTHIS( Font, NULL );
419 :
420 391209 : if( mpImplFont->meCharSet != eCharSet )
421 : {
422 263040 : MakeUnique();
423 263040 : mpImplFont->meCharSet = eCharSet;
424 : }
425 391209 : }
426 :
427 : // -----------------------------------------------------------------------
428 :
429 440116 : void Font::SetLanguage( LanguageType eLanguage )
430 : {
431 : DBG_CHKTHIS( Font, NULL );
432 :
433 440116 : if( mpImplFont->meLanguage != eLanguage )
434 : {
435 57872 : MakeUnique();
436 57872 : mpImplFont->meLanguage = eLanguage;
437 : }
438 440116 : }
439 :
440 : // -----------------------------------------------------------------------
441 :
442 93064 : void Font::SetCJKContextLanguage( LanguageType eLanguage )
443 : {
444 : DBG_CHKTHIS( Font, NULL );
445 :
446 93064 : if( mpImplFont->meCJKLanguage != eLanguage )
447 : {
448 56926 : MakeUnique();
449 56926 : mpImplFont->meCJKLanguage = eLanguage;
450 : }
451 93064 : }
452 :
453 : // -----------------------------------------------------------------------
454 :
455 389693 : void Font::SetPitch( FontPitch ePitch )
456 : {
457 : DBG_CHKTHIS( Font, NULL );
458 :
459 389693 : if( mpImplFont->mePitch != ePitch )
460 : {
461 190101 : MakeUnique();
462 190101 : mpImplFont->mePitch = ePitch;
463 : }
464 389693 : }
465 :
466 : // -----------------------------------------------------------------------
467 :
468 132245 : void Font::SetOrientation( short nOrientation )
469 : {
470 : DBG_CHKTHIS( Font, NULL );
471 :
472 132245 : if( mpImplFont->mnOrientation != nOrientation )
473 : {
474 1671 : MakeUnique();
475 1671 : mpImplFont->mnOrientation = nOrientation;
476 : }
477 132245 : }
478 :
479 : // -----------------------------------------------------------------------
480 :
481 38186 : void Font::SetVertical( sal_Bool bVertical )
482 : {
483 : DBG_CHKTHIS( Font, NULL );
484 :
485 38186 : if( mpImplFont->mbVertical != bVertical )
486 : {
487 0 : MakeUnique();
488 0 : mpImplFont->mbVertical = bVertical;
489 : }
490 38186 : }
491 :
492 : // -----------------------------------------------------------------------
493 :
494 213480 : void Font::SetKerning( FontKerning nKerning )
495 : {
496 : DBG_CHKTHIS( Font, NULL );
497 :
498 213480 : if( mpImplFont->mnKerning != nKerning )
499 : {
500 13844 : MakeUnique();
501 13844 : mpImplFont->mnKerning = nKerning;
502 : }
503 213480 : }
504 :
505 : // -----------------------------------------------------------------------
506 :
507 76 : sal_Bool Font::IsKerning() const
508 : {
509 76 : return (mpImplFont->mnKerning & KERNING_FONTSPECIFIC) != 0;
510 : }
511 :
512 : // -----------------------------------------------------------------------
513 :
514 416814 : void Font::SetWeight( FontWeight eWeight )
515 : {
516 : DBG_CHKTHIS( Font, NULL );
517 :
518 416814 : if( mpImplFont->meWeight != eWeight )
519 : {
520 208119 : MakeUnique();
521 208119 : mpImplFont->meWeight = eWeight;
522 : }
523 416814 : }
524 :
525 : // -----------------------------------------------------------------------
526 :
527 201958 : void Font::SetWidthType( FontWidth eWidth )
528 : {
529 : DBG_CHKTHIS( Font, NULL );
530 :
531 201958 : if( mpImplFont->meWidthType != eWidth )
532 : {
533 158006 : MakeUnique();
534 158006 : mpImplFont->meWidthType = eWidth;
535 : }
536 201958 : }
537 :
538 : // -----------------------------------------------------------------------
539 :
540 374682 : void Font::SetItalic( FontItalic eItalic )
541 : {
542 : DBG_CHKTHIS( Font, NULL );
543 :
544 374682 : if( mpImplFont->meItalic != eItalic )
545 : {
546 37610 : MakeUnique();
547 37610 : mpImplFont->meItalic = eItalic;
548 : }
549 374682 : }
550 :
551 : // -----------------------------------------------------------------------
552 :
553 137008 : void Font::SetOutline( sal_Bool bOutline )
554 : {
555 : DBG_CHKTHIS( Font, NULL );
556 :
557 137008 : if( mpImplFont->mbOutline != bOutline )
558 : {
559 0 : MakeUnique();
560 0 : mpImplFont->mbOutline = bOutline;
561 : }
562 137008 : }
563 :
564 : // -----------------------------------------------------------------------
565 :
566 136606 : void Font::SetShadow( sal_Bool bShadow )
567 : {
568 : DBG_CHKTHIS( Font, NULL );
569 :
570 136606 : if( mpImplFont->mbShadow != bShadow )
571 : {
572 8 : MakeUnique();
573 8 : mpImplFont->mbShadow = bShadow;
574 : }
575 136606 : }
576 :
577 : // -----------------------------------------------------------------------
578 :
579 138074 : void Font::SetUnderline( FontUnderline eUnderline )
580 : {
581 : DBG_CHKTHIS( Font, NULL );
582 :
583 138074 : if( mpImplFont->meUnderline != eUnderline )
584 : {
585 268 : MakeUnique();
586 268 : mpImplFont->meUnderline = eUnderline;
587 : }
588 138074 : }
589 :
590 : // -----------------------------------------------------------------------
591 :
592 136554 : void Font::SetOverline( FontUnderline eOverline )
593 : {
594 : DBG_CHKTHIS( Font, NULL );
595 :
596 136554 : if( mpImplFont->meOverline != eOverline )
597 : {
598 0 : MakeUnique();
599 0 : mpImplFont->meOverline = eOverline;
600 : }
601 136554 : }
602 :
603 : // -----------------------------------------------------------------------
604 :
605 137290 : void Font::SetStrikeout( FontStrikeout eStrikeout )
606 : {
607 : DBG_CHKTHIS( Font, NULL );
608 :
609 137290 : if( mpImplFont->meStrikeout != eStrikeout )
610 : {
611 76 : MakeUnique();
612 76 : mpImplFont->meStrikeout = eStrikeout;
613 : }
614 137290 : }
615 :
616 : // -----------------------------------------------------------------------
617 :
618 130404 : void Font::SetRelief( FontRelief eRelief )
619 : {
620 : DBG_CHKTHIS( Font, NULL );
621 :
622 130404 : if( mpImplFont->meRelief != eRelief )
623 : {
624 0 : MakeUnique();
625 0 : mpImplFont->meRelief = eRelief;
626 : }
627 130404 : }
628 :
629 : // -----------------------------------------------------------------------
630 :
631 135958 : void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark )
632 : {
633 : DBG_CHKTHIS( Font, NULL );
634 :
635 135958 : if( mpImplFont->meEmphasisMark != eEmphasisMark )
636 : {
637 0 : MakeUnique();
638 0 : mpImplFont->meEmphasisMark = eEmphasisMark;
639 : }
640 135958 : }
641 :
642 : // -----------------------------------------------------------------------
643 :
644 136486 : void Font::SetWordLineMode( sal_Bool bWordLine )
645 : {
646 : DBG_CHKTHIS( Font, NULL );
647 :
648 136486 : if( mpImplFont->mbWordLine != bWordLine )
649 : {
650 0 : MakeUnique();
651 0 : mpImplFont->mbWordLine = bWordLine;
652 : }
653 136486 : }
654 :
655 : // -----------------------------------------------------------------------
656 :
657 782303 : 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 782303 : if ( rFont.mpImplFont->mnRefCount )
666 780836 : rFont.mpImplFont->mnRefCount++;
667 :
668 : // Wenn es keine statischen ImplDaten sind, dann loeschen, wenn es
669 : // die letzte Referenz ist, sonst Referenzcounter decrementieren
670 782303 : if ( mpImplFont->mnRefCount )
671 : {
672 473297 : if ( mpImplFont->mnRefCount == 1 )
673 181534 : delete mpImplFont;
674 : else
675 291763 : mpImplFont->mnRefCount--;
676 : }
677 :
678 782303 : mpImplFont = rFont.mpImplFont;
679 :
680 782303 : return *this;
681 : }
682 :
683 : // -----------------------------------------------------------------------
684 :
685 232429 : sal_Bool Font::operator==( const Font& rFont ) const
686 : {
687 : DBG_CHKTHIS( Font, NULL );
688 : DBG_CHKOBJ( &rFont, Font, NULL );
689 :
690 232429 : if( mpImplFont == rFont.mpImplFont )
691 92078 : return sal_True;
692 140351 : if( *mpImplFont == *rFont.mpImplFont )
693 96645 : return sal_True;
694 :
695 43706 : return sal_False;
696 : }
697 :
698 : // -----------------------------------------------------------------------
699 :
700 58 : void Font::Merge( const Font& rFont )
701 : {
702 58 : if ( rFont.GetName().Len() )
703 : {
704 58 : SetName( rFont.GetName() );
705 58 : SetStyleName( rFont.GetStyleName() );
706 58 : SetCharSet( GetCharSet() );
707 58 : SetLanguage( rFont.GetLanguage() );
708 58 : SetCJKContextLanguage( rFont.GetCJKContextLanguage() );
709 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
710 58 : SetFamily( rFont.mpImplFont->meFamily );
711 58 : SetPitch( rFont.mpImplFont->mePitch );
712 : }
713 :
714 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
715 58 : if ( rFont.mpImplFont->meWeight != WEIGHT_DONTKNOW )
716 58 : SetWeight( rFont.GetWeight() );
717 58 : if ( rFont.mpImplFont->meItalic != ITALIC_DONTKNOW )
718 58 : SetItalic( rFont.GetItalic() );
719 58 : if ( rFont.mpImplFont->meWidthType != WIDTH_DONTKNOW )
720 0 : SetWidthType( rFont.GetWidthType() );
721 :
722 :
723 58 : if ( rFont.GetSize().Height() )
724 58 : SetSize( rFont.GetSize() );
725 58 : if ( rFont.GetUnderline() != UNDERLINE_DONTKNOW )
726 : {
727 58 : SetUnderline( rFont.GetUnderline() );
728 58 : SetWordLineMode( rFont.IsWordLineMode() );
729 : }
730 58 : if ( rFont.GetOverline() != UNDERLINE_DONTKNOW )
731 : {
732 58 : SetOverline( rFont.GetOverline() );
733 58 : SetWordLineMode( rFont.IsWordLineMode() );
734 : }
735 58 : if ( rFont.GetStrikeout() != STRIKEOUT_DONTKNOW )
736 : {
737 58 : SetStrikeout( rFont.GetStrikeout() );
738 58 : SetWordLineMode( rFont.IsWordLineMode() );
739 : }
740 :
741 : // Defaults?
742 58 : SetOrientation( rFont.GetOrientation() );
743 58 : SetVertical( rFont.IsVertical() );
744 58 : SetEmphasisMark( rFont.GetEmphasisMark() );
745 58 : SetKerning( rFont.IsKerning() );
746 58 : SetOutline( rFont.IsOutline() );
747 58 : SetShadow( rFont.IsShadow() );
748 58 : SetRelief( rFont.GetRelief() );
749 58 : }
750 :
751 134593 : void Font::GetFontAttributes( ImplFontAttributes& rAttrs ) const
752 : {
753 : // #i56788# Use members directly, don't risc config access.
754 134593 : rAttrs.maName = mpImplFont->maFamilyName;
755 134593 : rAttrs.maStyleName = mpImplFont->maStyleName;
756 134593 : rAttrs.meFamily = mpImplFont->meFamily;
757 134593 : rAttrs.mePitch = mpImplFont->mePitch;
758 134593 : rAttrs.meItalic = mpImplFont->meItalic;
759 134593 : rAttrs.meWeight = mpImplFont->meWeight;
760 134593 : rAttrs.meWidthType = WIDTH_DONTKNOW;
761 134593 : rAttrs.mbSymbolFlag= (mpImplFont->meCharSet == RTL_TEXTENCODING_SYMBOL);
762 134593 : }
763 :
764 :
765 : // -----------------------------------------------------------------------
766 :
767 43842 : SvStream& operator>>( SvStream& rIStm, Impl_Font& rImpl_Font )
768 : {
769 43842 : VersionCompat aCompat( rIStm, STREAM_READ );
770 : sal_uInt16 nTmp16;
771 : sal_Bool bTmp;
772 : sal_uInt8 nTmp8;
773 :
774 43842 : rImpl_Font.maFamilyName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
775 43842 : rImpl_Font.maStyleName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
776 43842 : rIStm >> rImpl_Font.maSize;
777 :
778 43842 : rIStm >> nTmp16; rImpl_Font.meCharSet = (rtl_TextEncoding) nTmp16;
779 43842 : rIStm >> nTmp16; rImpl_Font.meFamily = (FontFamily) nTmp16;
780 43842 : rIStm >> nTmp16; rImpl_Font.mePitch = (FontPitch) nTmp16;
781 43842 : rIStm >> nTmp16; rImpl_Font.meWeight = (FontWeight) nTmp16;
782 43842 : rIStm >> nTmp16; rImpl_Font.meUnderline = (FontUnderline) nTmp16;
783 43842 : rIStm >> nTmp16; rImpl_Font.meStrikeout = (FontStrikeout) nTmp16;
784 43842 : rIStm >> nTmp16; rImpl_Font.meItalic = (FontItalic) nTmp16;
785 43842 : rIStm >> nTmp16; rImpl_Font.meLanguage = (LanguageType) nTmp16;
786 43842 : rIStm >> nTmp16; rImpl_Font.meWidthType = (FontWidth) nTmp16;
787 :
788 43842 : rIStm >> rImpl_Font.mnOrientation;
789 :
790 43842 : rIStm >> bTmp; rImpl_Font.mbWordLine = bTmp;
791 43842 : rIStm >> bTmp; rImpl_Font.mbOutline = bTmp;
792 43842 : rIStm >> bTmp; rImpl_Font.mbShadow = bTmp;
793 43842 : rIStm >> nTmp8; rImpl_Font.mnKerning = nTmp8;
794 :
795 43842 : if( aCompat.GetVersion() >= 2 )
796 : {
797 43842 : rIStm >> nTmp8; rImpl_Font.meRelief = (FontRelief)nTmp8;
798 43842 : rIStm >> nTmp16; rImpl_Font.meCJKLanguage = (LanguageType)nTmp16;
799 43842 : rIStm >> bTmp; rImpl_Font.mbVertical = bTmp;
800 43842 : rIStm >> nTmp16; rImpl_Font.meEmphasisMark = (FontEmphasisMark)nTmp16;
801 : }
802 43842 : if( aCompat.GetVersion() >= 3 )
803 : {
804 43842 : rIStm >> nTmp16; rImpl_Font.meOverline = (FontUnderline) nTmp16;
805 : }
806 : // Relief
807 : // CJKContextLanguage
808 :
809 43842 : return rIStm;
810 : }
811 :
812 : // -----------------------------------------------------------------------
813 :
814 46660 : SvStream& operator<<( SvStream& rOStm, const Impl_Font& rImpl_Font )
815 : {
816 46660 : VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
817 46660 : rOStm.WriteUniOrByteString( rImpl_Font.maFamilyName, rOStm.GetStreamCharSet() );
818 46660 : rOStm.WriteUniOrByteString( rImpl_Font.maStyleName, rOStm.GetStreamCharSet() );
819 46660 : rOStm << rImpl_Font.maSize;
820 :
821 46660 : rOStm << (sal_uInt16) GetStoreCharSet( rImpl_Font.meCharSet );
822 46660 : rOStm << (sal_uInt16) rImpl_Font.meFamily;
823 46660 : rOStm << (sal_uInt16) rImpl_Font.mePitch;
824 46660 : rOStm << (sal_uInt16) rImpl_Font.meWeight;
825 46660 : rOStm << (sal_uInt16) rImpl_Font.meUnderline;
826 46660 : rOStm << (sal_uInt16) rImpl_Font.meStrikeout;
827 46660 : rOStm << (sal_uInt16) rImpl_Font.meItalic;
828 46660 : rOStm << (sal_uInt16) rImpl_Font.meLanguage;
829 46660 : rOStm << (sal_uInt16) rImpl_Font.meWidthType;
830 :
831 46660 : rOStm << rImpl_Font.mnOrientation;
832 :
833 46660 : rOStm << (sal_Bool) rImpl_Font.mbWordLine;
834 46660 : rOStm << (sal_Bool) rImpl_Font.mbOutline;
835 46660 : rOStm << (sal_Bool) rImpl_Font.mbShadow;
836 46660 : rOStm << (sal_uInt8) rImpl_Font.mnKerning;
837 :
838 : // new in version 2
839 46660 : rOStm << (sal_uInt8) rImpl_Font.meRelief;
840 46660 : rOStm << (sal_uInt16) rImpl_Font.meCJKLanguage;
841 46660 : rOStm << (sal_Bool) rImpl_Font.mbVertical;
842 46660 : rOStm << (sal_uInt16) rImpl_Font.meEmphasisMark;
843 :
844 : // new in version 3
845 46660 : rOStm << (sal_uInt16) rImpl_Font.meOverline;
846 :
847 46660 : return rOStm;
848 : }
849 :
850 : // -----------------------------------------------------------------------
851 :
852 43842 : SvStream& operator>>( SvStream& rIStm, Font& rFont )
853 : {
854 43842 : rFont.MakeUnique();
855 43842 : return( rIStm >> *rFont.mpImplFont );
856 : }
857 :
858 : // -----------------------------------------------------------------------
859 :
860 46660 : SvStream& operator<<( SvStream& rOStm, const Font& rFont )
861 : {
862 46660 : 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 488420 : const Color& Font::GetColor() const { return mpImplFont->maColor; }
1077 44978 : const Color& Font::GetFillColor() const { return mpImplFont->maFillColor; }
1078 91928 : sal_Bool Font::IsTransparent() const { return mpImplFont->mbTransparent; }
1079 205547 : FontAlign Font::GetAlign() const { return mpImplFont->meAlign; }
1080 568286 : const String& Font::GetName() const { return mpImplFont->maFamilyName; }
1081 2759 : const String& Font::GetStyleName() const { return mpImplFont->maStyleName; }
1082 544033 : const Size& Font::GetSize() const { return mpImplFont->maSize; }
1083 34188 : void Font::SetHeight( long nHeight ) { SetSize( Size( mpImplFont->maSize.Width(), nHeight ) ); }
1084 143911 : long Font::GetHeight() const { return mpImplFont->maSize.Height(); }
1085 0 : void Font::SetWidth( long nWidth ) { SetSize( Size( nWidth, mpImplFont->maSize.Height() ) ); }
1086 130 : long Font::GetWidth() const { return mpImplFont->maSize.Width(); }
1087 174663 : rtl_TextEncoding Font::GetCharSet() const { return mpImplFont->meCharSet; }
1088 387545 : LanguageType Font::GetLanguage() const { return mpImplFont->meLanguage; }
1089 58 : LanguageType Font::GetCJKContextLanguage() const { return mpImplFont->meCJKLanguage; }
1090 140702 : short Font::GetOrientation() const { return mpImplFont->mnOrientation; }
1091 249198 : sal_Bool Font::IsVertical() const { return mpImplFont->mbVertical; }
1092 482987 : FontKerning Font::GetKerning() const { return mpImplFont->mnKerning; }
1093 17416 : FontPitch Font::GetPitch() const { return mpImplFont->GetPitch(); }
1094 92646 : FontWeight Font::GetWeight() const { return mpImplFont->GetWeight(); }
1095 0 : FontWidth Font::GetWidthType() const { return mpImplFont->GetWidthType(); }
1096 423026 : FontItalic Font::GetItalic() const { return mpImplFont->GetItalic(); }
1097 17046 : FontFamily Font::GetFamily() const { return mpImplFont->GetFamily(); }
1098 102635 : sal_Bool Font::IsOutline() const { return mpImplFont->mbOutline; }
1099 102639 : sal_Bool Font::IsShadow() const { return mpImplFont->mbShadow; }
1100 104449 : FontRelief Font::GetRelief() const { return mpImplFont->meRelief; }
1101 124885 : FontUnderline Font::GetUnderline() const { return mpImplFont->meUnderline; }
1102 115858 : FontUnderline Font::GetOverline() const { return mpImplFont->meOverline; }
1103 117454 : FontStrikeout Font::GetStrikeout() const { return mpImplFont->meStrikeout; }
1104 120453 : FontEmphasisMark Font::GetEmphasisMark() const { return mpImplFont->meEmphasisMark; }
1105 18717 : sal_Bool Font::IsWordLineMode() const { return mpImplFont->mbWordLine; }
1106 359539 : sal_Bool Font::IsSameInstance( const Font& rFont ) const { return (mpImplFont == rFont.mpImplFont); }
1107 :
1108 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|