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 : #include "unotools/fontcfg.hxx"
21 :
22 : #include "tools/stream.hxx"
23 : #include "tools/vcompat.hxx"
24 : #include "tools/debug.hxx"
25 : #include <tools/gen.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 41644 : Impl_Font::Impl_Font() :
40 : maColor( COL_TRANSPARENT ),
41 : maFillColor( COL_TRANSPARENT ),
42 : maLanguageTag( LANGUAGE_DONTKNOW ),
43 41644 : maCJKLanguageTag( LANGUAGE_DONTKNOW )
44 : {
45 41644 : mnRefCount = 1;
46 41644 : meCharSet = RTL_TEXTENCODING_DONTKNOW;
47 41644 : meFamily = FAMILY_DONTKNOW;
48 41644 : mePitch = PITCH_DONTKNOW;
49 41644 : meAlign = ALIGN_TOP;
50 41644 : meWeight = WEIGHT_DONTKNOW;
51 41644 : meWidthType = WIDTH_DONTKNOW;
52 41644 : meItalic = ITALIC_NONE;
53 41644 : meUnderline = UNDERLINE_NONE;
54 41644 : meOverline = UNDERLINE_NONE;
55 41644 : meStrikeout = STRIKEOUT_NONE;
56 41644 : meRelief = RELIEF_NONE;
57 41644 : meEmphasisMark = EMPHASISMARK_NONE;
58 41644 : mnOrientation = 0;
59 41644 : mnKerning = 0;
60 41644 : mbWordLine = false;
61 41644 : mbOutline = false;
62 41644 : mbShadow = false;
63 41644 : mbVertical = false;
64 41644 : mbTransparent = true;
65 41644 : mbConfigLookup = false;
66 41644 : }
67 :
68 9001111 : Impl_Font::Impl_Font( const Impl_Font& rImplFont )
69 : : maFamilyName( rImplFont.maFamilyName ),
70 : maStyleName( rImplFont.maStyleName ),
71 : maSize( rImplFont.maSize ),
72 : maColor( rImplFont.maColor ),
73 : maFillColor( rImplFont.maFillColor ),
74 : maLanguageTag( rImplFont.maLanguageTag ),
75 9001111 : maCJKLanguageTag( rImplFont.maCJKLanguageTag )
76 : {
77 9001111 : mnRefCount = 1;
78 9001111 : meCharSet = rImplFont.meCharSet;
79 9001111 : meFamily = rImplFont.meFamily;
80 9001111 : mePitch = rImplFont.mePitch;
81 9001111 : meAlign = rImplFont.meAlign;
82 9001111 : meWeight = rImplFont.meWeight;
83 9001111 : meWidthType = rImplFont.meWidthType;
84 9001111 : meItalic = rImplFont.meItalic;
85 9001111 : meUnderline = rImplFont.meUnderline;
86 9001111 : meOverline = rImplFont.meOverline;
87 9001111 : meStrikeout = rImplFont.meStrikeout;
88 9001111 : meRelief = rImplFont.meRelief;
89 9001111 : meEmphasisMark = rImplFont.meEmphasisMark;
90 9001111 : mnOrientation = rImplFont.mnOrientation;
91 9001111 : mnKerning = rImplFont.mnKerning;
92 9001111 : mbWordLine = rImplFont.mbWordLine;
93 9001111 : mbOutline = rImplFont.mbOutline;
94 9001111 : mbShadow = rImplFont.mbShadow;
95 9001111 : mbVertical = rImplFont.mbVertical;
96 9001111 : mbTransparent = rImplFont.mbTransparent;
97 9001111 : mbConfigLookup = rImplFont.mbConfigLookup;
98 9001111 : }
99 :
100 1382706 : bool Impl_Font::operator==( const Impl_Font& rOther ) const
101 : {
102 : // equality tests split up for easier debugging
103 1382706 : if( (meWeight != rOther.meWeight)
104 1209477 : || (meItalic != rOther.meItalic)
105 1185195 : || (meFamily != rOther.meFamily)
106 1062884 : || (mePitch != rOther.mePitch) )
107 320192 : return false;
108 :
109 2125028 : if( (meCharSet != rOther.meCharSet)
110 1053712 : || (maLanguageTag != rOther.maLanguageTag)
111 1037981 : || (maCJKLanguageTag != rOther.maCJKLanguageTag)
112 2096573 : || (meAlign != rOther.meAlign) )
113 28503 : return false;
114 :
115 2068022 : if( (maSize != rOther.maSize)
116 887728 : || (mnOrientation != rOther.mnOrientation)
117 1920995 : || (mbVertical != rOther.mbVertical) )
118 147027 : return false;
119 :
120 1773968 : if( (maFamilyName != rOther.maFamilyName)
121 886984 : || (maStyleName != rOther.maStyleName) )
122 11595 : return false;
123 :
124 1750778 : if( (maColor != rOther.maColor)
125 875389 : || (maFillColor != rOther.maFillColor) )
126 17844 : return false;
127 :
128 857545 : if( (meUnderline != rOther.meUnderline)
129 848260 : || (meOverline != rOther.meOverline)
130 847994 : || (meStrikeout != rOther.meStrikeout)
131 847074 : || (meRelief != rOther.meRelief)
132 845551 : || (meEmphasisMark != rOther.meEmphasisMark)
133 844635 : || (mbWordLine != rOther.mbWordLine)
134 844404 : || (mbOutline != rOther.mbOutline)
135 844038 : || (mbShadow != rOther.mbShadow)
136 843906 : || (mnKerning != rOther.mnKerning)
137 840429 : || (mbTransparent != rOther.mbTransparent) )
138 17116 : return false;
139 :
140 840429 : return true;
141 : }
142 :
143 49961 : void Impl_Font::AskConfig()
144 : {
145 49961 : if( mbConfigLookup )
146 91039 : return;
147 :
148 8883 : mbConfigLookup = true;
149 :
150 : // prepare the FontSubst configuration lookup
151 8883 : const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
152 :
153 8883 : OUString aShortName;
154 17766 : OUString aFamilyName;
155 8883 : sal_uLong nType = 0;
156 8883 : FontWeight eWeight = WEIGHT_DONTKNOW;
157 8883 : FontWidth eWidthType = WIDTH_DONTKNOW;
158 17766 : OUString aMapName = GetEnglishSearchFontName( maFamilyName );
159 :
160 : utl::FontSubstConfiguration::getMapName( aMapName,
161 8883 : aShortName, aFamilyName, eWeight, eWidthType, nType );
162 :
163 : // lookup the font name in the configuration
164 8883 : const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
165 :
166 : // if the direct lookup failed try again with an alias name
167 8883 : if ( !pFontAttr && (aShortName != aMapName) )
168 0 : pFontAttr = rFontSubst.getSubstInfo( aShortName );
169 :
170 8883 : if( pFontAttr )
171 : {
172 : // the font was found in the configuration
173 8325 : if( meFamily == FAMILY_DONTKNOW )
174 : {
175 5394 : if ( pFontAttr->Type & IMPL_FONT_ATTR_SERIF )
176 1415 : meFamily = FAMILY_ROMAN;
177 3979 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_SANSSERIF )
178 1676 : meFamily = FAMILY_SWISS;
179 2303 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_TYPEWRITER )
180 98 : meFamily = FAMILY_MODERN;
181 2205 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_ITALIC )
182 0 : meFamily = FAMILY_SCRIPT;
183 2205 : else if ( pFontAttr->Type & IMPL_FONT_ATTR_DECORATIVE )
184 0 : meFamily = FAMILY_DECORATIVE;
185 : }
186 :
187 8325 : if( mePitch == PITCH_DONTKNOW )
188 : {
189 5289 : if ( pFontAttr->Type & IMPL_FONT_ATTR_FIXED )
190 126 : mePitch = PITCH_FIXED;
191 : }
192 : }
193 :
194 : // if some attributes are still unknown then use the FontSubst magic
195 8883 : if( meFamily == FAMILY_DONTKNOW )
196 : {
197 2313 : if( nType & IMPL_FONT_ATTR_SERIF )
198 10 : meFamily = FAMILY_ROMAN;
199 2303 : else if( nType & IMPL_FONT_ATTR_SANSSERIF )
200 4 : meFamily = FAMILY_SWISS;
201 2299 : else if( nType & IMPL_FONT_ATTR_TYPEWRITER )
202 0 : meFamily = FAMILY_MODERN;
203 2299 : else if( nType & IMPL_FONT_ATTR_ITALIC )
204 0 : meFamily = FAMILY_SCRIPT;
205 2299 : else if( nType & IMPL_FONT_ATTR_DECORATIVE )
206 0 : meFamily = FAMILY_DECORATIVE;
207 : }
208 :
209 8883 : if( meWeight == WEIGHT_DONTKNOW )
210 3878 : meWeight = eWeight;
211 8883 : if( meWidthType == WIDTH_DONTKNOW )
212 16291 : meWidthType = eWidthType;
213 : }
214 :
215 30454556 : void Font::MakeUnique()
216 : {
217 : // create a copy if others still reference it
218 30454556 : if ( mpImplFont->mnRefCount != 1 )
219 : {
220 9001111 : if ( mpImplFont->mnRefCount )
221 2999588 : mpImplFont->mnRefCount--;
222 9001111 : mpImplFont = new Impl_Font( *mpImplFont );
223 : }
224 30454556 : }
225 :
226 7786687 : Font::Font()
227 : {
228 :
229 7786687 : static Impl_Font aStaticImplFont;
230 : // RefCount is zero for static objects
231 7786687 : aStaticImplFont.mnRefCount = 0;
232 7786687 : mpImplFont = &aStaticImplFont;
233 7786687 : }
234 :
235 7751953 : Font::Font( const vcl::Font& rFont )
236 : {
237 7751953 : bool bRefIncrementable = rFont.mpImplFont->mnRefCount < ::std::numeric_limits<sal_uInt32>::max();
238 : DBG_ASSERT( bRefIncrementable, "Font: RefCount overflow" );
239 :
240 7751953 : mpImplFont = rFont.mpImplFont;
241 : // do not count static objects (where RefCount is zero)
242 7751953 : if ( mpImplFont->mnRefCount && bRefIncrementable )
243 7732084 : mpImplFont->mnRefCount++;
244 7751953 : }
245 :
246 7562 : Font::Font( const OUString& rFamilyName, const Size& rSize )
247 : {
248 :
249 7562 : mpImplFont = new Impl_Font;
250 7562 : mpImplFont->maFamilyName = rFamilyName;
251 7562 : mpImplFont->maSize = rSize;
252 7562 : }
253 :
254 32906 : Font::Font( const OUString& rFamilyName, const OUString& rStyleName, const Size& rSize )
255 : {
256 :
257 32906 : mpImplFont = new Impl_Font;
258 32906 : mpImplFont->maFamilyName= rFamilyName;
259 32906 : mpImplFont->maStyleName = rStyleName;
260 32906 : mpImplFont->maSize = rSize;
261 32906 : }
262 :
263 837 : Font::Font( FontFamily eFamily, const Size& rSize )
264 : {
265 :
266 837 : mpImplFont = new Impl_Font;
267 837 : mpImplFont->meFamily = eFamily;
268 837 : mpImplFont->maSize = rSize;
269 837 : }
270 :
271 15573521 : Font::~Font()
272 : {
273 :
274 : // decrement reference counter and delete if last reference
275 : // if the object is not static (Refcounter==0)
276 15573521 : if ( mpImplFont->mnRefCount )
277 : {
278 15079650 : if ( mpImplFont->mnRefCount == 1 )
279 4282778 : delete mpImplFont;
280 : else
281 10796872 : mpImplFont->mnRefCount--;
282 : }
283 15573521 : }
284 :
285 1568277 : void Font::SetColor( const Color& rColor )
286 : {
287 :
288 1568277 : if( mpImplFont->maColor != rColor )
289 : {
290 554089 : MakeUnique();
291 554089 : mpImplFont->maColor = rColor;
292 : }
293 1568277 : }
294 :
295 856699 : void Font::SetFillColor( const Color& rColor )
296 : {
297 :
298 856699 : MakeUnique();
299 856699 : mpImplFont->maFillColor = rColor;
300 856699 : if ( rColor.GetTransparency() )
301 816133 : mpImplFont->mbTransparent = true;
302 856699 : if (GetUnderline() == UNDERLINE_SINGLE ) {
303 : SAL_INFO("vcl.gdi", "I'm setting a filling (from Font) of (" << rColor.GetRed() << "," << rColor.GetGreen() << "," << rColor.GetBlue() << ")");
304 : }
305 856699 : }
306 :
307 1522816 : void Font::SetTransparent( bool bTransparent )
308 : {
309 :
310 1522816 : if( mpImplFont->mbTransparent != bTransparent )
311 : {
312 34333 : MakeUnique();
313 34333 : mpImplFont->mbTransparent = bTransparent;
314 : }
315 1522816 : }
316 :
317 1557513 : void Font::SetAlign( FontAlign eAlign )
318 : {
319 :
320 1557513 : if( mpImplFont->meAlign != eAlign )
321 : {
322 474215 : MakeUnique();
323 474215 : mpImplFont->meAlign = eAlign;
324 : }
325 1557513 : }
326 :
327 4306201 : void Font::SetName( const OUString& rFamilyName )
328 : {
329 :
330 4306201 : MakeUnique();
331 4306201 : mpImplFont->maFamilyName = rFamilyName;
332 4306201 : }
333 :
334 2729388 : void Font::SetStyleName( const OUString& rStyleName )
335 : {
336 :
337 2729388 : MakeUnique();
338 2729388 : mpImplFont->maStyleName = rStyleName;
339 2729388 : }
340 :
341 3114839 : void Font::SetSize( const Size& rSize )
342 : {
343 :
344 3114839 : if( mpImplFont->maSize != rSize )
345 : {
346 2438702 : MakeUnique();
347 2438702 : mpImplFont->maSize = rSize;
348 : }
349 3114839 : }
350 :
351 3895316 : void Font::SetFamily( FontFamily eFamily )
352 : {
353 :
354 3895316 : if( mpImplFont->meFamily != eFamily )
355 : {
356 1409740 : MakeUnique();
357 1409740 : mpImplFont->meFamily = eFamily;
358 : }
359 3895316 : }
360 :
361 3957846 : void Font::SetCharSet( rtl_TextEncoding eCharSet )
362 : {
363 :
364 3957846 : if( mpImplFont->meCharSet != eCharSet )
365 : {
366 3011188 : MakeUnique();
367 3011188 : mpImplFont->meCharSet = eCharSet;
368 : }
369 3957846 : }
370 :
371 7583 : void Font::SetLanguageTag( const LanguageTag& rLanguageTag )
372 : {
373 :
374 7583 : if( mpImplFont->maLanguageTag != rLanguageTag )
375 : {
376 0 : MakeUnique();
377 0 : mpImplFont->maLanguageTag = rLanguageTag;
378 : }
379 7583 : }
380 :
381 7583 : void Font::SetCJKContextLanguageTag( const LanguageTag& rLanguageTag )
382 : {
383 :
384 7583 : if( mpImplFont->maCJKLanguageTag != rLanguageTag )
385 : {
386 0 : MakeUnique();
387 0 : mpImplFont->maCJKLanguageTag = rLanguageTag;
388 : }
389 7583 : }
390 :
391 7052018 : void Font::SetLanguage( LanguageType eLanguage )
392 : {
393 :
394 7052018 : if( mpImplFont->maLanguageTag.getLanguageType( false) != eLanguage )
395 : {
396 4648736 : MakeUnique();
397 4648736 : mpImplFont->maLanguageTag.reset( eLanguage);
398 : }
399 7052018 : }
400 :
401 983053 : void Font::SetCJKContextLanguage( LanguageType eLanguage )
402 : {
403 :
404 983053 : if( mpImplFont->maCJKLanguageTag.getLanguageType( false) != eLanguage )
405 : {
406 771733 : MakeUnique();
407 771733 : mpImplFont->maCJKLanguageTag.reset( eLanguage);
408 : }
409 983053 : }
410 :
411 3926902 : void Font::SetPitch( FontPitch ePitch )
412 : {
413 :
414 3926902 : if( mpImplFont->mePitch != ePitch )
415 : {
416 2592478 : MakeUnique();
417 2592478 : mpImplFont->mePitch = ePitch;
418 : }
419 3926902 : }
420 :
421 845605 : void Font::SetOrientation( short nOrientation )
422 : {
423 :
424 845605 : if( mpImplFont->mnOrientation != nOrientation )
425 : {
426 33579 : MakeUnique();
427 33579 : mpImplFont->mnOrientation = nOrientation;
428 : }
429 845605 : }
430 :
431 283289 : void Font::SetVertical( bool bVertical )
432 : {
433 :
434 283289 : if( mpImplFont->mbVertical != bVertical )
435 : {
436 34 : MakeUnique();
437 34 : mpImplFont->mbVertical = bVertical;
438 : }
439 283289 : }
440 :
441 1257034 : void Font::SetKerning( FontKerning nKerning )
442 : {
443 :
444 1257034 : if( mpImplFont->mnKerning != nKerning )
445 : {
446 422287 : MakeUnique();
447 422287 : mpImplFont->mnKerning = nKerning;
448 : }
449 1257034 : }
450 :
451 13363 : bool Font::IsKerning() const
452 : {
453 13363 : return (mpImplFont->mnKerning & KERNING_FONTSPECIFIC) != 0;
454 : }
455 :
456 4012218 : void Font::SetWeight( FontWeight eWeight )
457 : {
458 :
459 4012218 : if( mpImplFont->meWeight != eWeight )
460 : {
461 2673142 : MakeUnique();
462 2673142 : mpImplFont->meWeight = eWeight;
463 : }
464 4012218 : }
465 :
466 2247303 : void Font::SetWidthType( FontWidth eWidth )
467 : {
468 :
469 2247303 : if( mpImplFont->meWidthType != eWidth )
470 : {
471 2245223 : MakeUnique();
472 2245223 : mpImplFont->meWidthType = eWidth;
473 : }
474 2247303 : }
475 :
476 3608979 : void Font::SetItalic( FontItalic eItalic )
477 : {
478 :
479 3608979 : if( mpImplFont->meItalic != eItalic )
480 : {
481 839244 : MakeUnique();
482 839244 : mpImplFont->meItalic = eItalic;
483 : }
484 3608979 : }
485 :
486 1198514 : void Font::SetOutline( bool bOutline )
487 : {
488 :
489 1198514 : if( mpImplFont->mbOutline != bOutline )
490 : {
491 25228 : MakeUnique();
492 25228 : mpImplFont->mbOutline = bOutline;
493 : }
494 1198514 : }
495 :
496 1167159 : void Font::SetShadow( bool bShadow )
497 : {
498 :
499 1167159 : if( mpImplFont->mbShadow != bShadow )
500 : {
501 24977 : MakeUnique();
502 24977 : mpImplFont->mbShadow = bShadow;
503 : }
504 1167159 : }
505 :
506 1287684 : void Font::SetUnderline( FontUnderline eUnderline )
507 : {
508 :
509 1287684 : if( mpImplFont->meUnderline != eUnderline )
510 : {
511 115394 : MakeUnique();
512 115394 : mpImplFont->meUnderline = eUnderline;
513 : }
514 1287684 : }
515 :
516 1182050 : void Font::SetOverline( FontUnderline eOverline )
517 : {
518 :
519 1182050 : if( mpImplFont->meOverline != eOverline )
520 : {
521 17229 : MakeUnique();
522 17229 : mpImplFont->meOverline = eOverline;
523 : }
524 1182050 : }
525 :
526 1196103 : void Font::SetStrikeout( FontStrikeout eStrikeout )
527 : {
528 :
529 1196103 : if( mpImplFont->meStrikeout != eStrikeout )
530 : {
531 49292 : MakeUnique();
532 49292 : mpImplFont->meStrikeout = eStrikeout;
533 : }
534 1196103 : }
535 :
536 858582 : void Font::SetRelief( FontRelief eRelief )
537 : {
538 :
539 858582 : if( mpImplFont->meRelief != eRelief )
540 : {
541 36607 : MakeUnique();
542 36607 : mpImplFont->meRelief = eRelief;
543 : }
544 858582 : }
545 :
546 1165151 : void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark )
547 : {
548 :
549 1165151 : if( mpImplFont->meEmphasisMark != eEmphasisMark )
550 : {
551 38625 : MakeUnique();
552 38625 : mpImplFont->meEmphasisMark = eEmphasisMark;
553 : }
554 1165151 : }
555 :
556 1185262 : void Font::SetWordLineMode( bool bWordLine )
557 : {
558 :
559 1185262 : if( mpImplFont->mbWordLine != bWordLine )
560 : {
561 30607 : MakeUnique();
562 30607 : mpImplFont->mbWordLine = bWordLine;
563 : }
564 1185262 : }
565 :
566 7820750 : Font& Font::operator=( const vcl::Font& rFont )
567 : {
568 7820750 : bool bRefIncrementable = rFont.mpImplFont->mnRefCount < ::std::numeric_limits<sal_uInt32>::max();
569 : DBG_ASSERT( bRefIncrementable, "Font: RefCount overflow" );
570 :
571 : // Increment RefCount first, so that we can reference ourselves
572 : // RefCount == 0 for static objects
573 7820750 : if ( rFont.mpImplFont->mnRefCount && bRefIncrementable )
574 7800782 : rFont.mpImplFont->mnRefCount++;
575 :
576 : // If it's not static ImplData and if it's the last reference, delete it
577 : // else decrement RefCount
578 7820750 : if ( mpImplFont->mnRefCount )
579 : {
580 6489967 : if ( mpImplFont->mnRefCount == 1 )
581 4755329 : delete mpImplFont;
582 : else
583 1734638 : mpImplFont->mnRefCount--;
584 : }
585 :
586 7820750 : mpImplFont = rFont.mpImplFont;
587 :
588 7820750 : return *this;
589 : }
590 :
591 2797180 : bool Font::operator==( const vcl::Font& rFont ) const
592 : {
593 2797180 : return mpImplFont == rFont.mpImplFont || *mpImplFont == *rFont.mpImplFont;
594 : }
595 :
596 7647 : void Font::Merge( const vcl::Font& rFont )
597 : {
598 7647 : if ( !rFont.GetName().isEmpty() )
599 : {
600 7583 : SetName( rFont.GetName() );
601 7583 : SetStyleName( rFont.GetStyleName() );
602 7583 : SetCharSet( GetCharSet() );
603 7583 : SetLanguageTag( rFont.GetLanguageTag() );
604 7583 : SetCJKContextLanguageTag( rFont.GetCJKContextLanguageTag() );
605 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
606 7583 : SetFamily( rFont.mpImplFont->meFamily );
607 7583 : SetPitch( rFont.mpImplFont->mePitch );
608 : }
609 :
610 : // don't use access methods here, might lead to AskConfig(), if DONTKNOW
611 7647 : if ( rFont.mpImplFont->meWeight != WEIGHT_DONTKNOW )
612 7597 : SetWeight( rFont.GetWeight() );
613 7647 : if ( rFont.mpImplFont->meItalic != ITALIC_DONTKNOW )
614 5002 : SetItalic( rFont.GetItalic() );
615 7647 : if ( rFont.mpImplFont->meWidthType != WIDTH_DONTKNOW )
616 6893 : SetWidthType( rFont.GetWidthType() );
617 :
618 7647 : if ( rFont.GetSize().Height() )
619 7583 : SetSize( rFont.GetSize() );
620 7647 : if ( rFont.GetUnderline() != UNDERLINE_DONTKNOW )
621 : {
622 7647 : SetUnderline( rFont.GetUnderline() );
623 7647 : SetWordLineMode( rFont.IsWordLineMode() );
624 : }
625 7647 : if ( rFont.GetOverline() != UNDERLINE_DONTKNOW )
626 : {
627 7647 : SetOverline( rFont.GetOverline() );
628 7647 : SetWordLineMode( rFont.IsWordLineMode() );
629 : }
630 7647 : if ( rFont.GetStrikeout() != STRIKEOUT_DONTKNOW )
631 : {
632 7647 : SetStrikeout( rFont.GetStrikeout() );
633 7647 : SetWordLineMode( rFont.IsWordLineMode() );
634 : }
635 :
636 : // Defaults?
637 7647 : SetOrientation( rFont.GetOrientation() );
638 7647 : SetVertical( rFont.IsVertical() );
639 7647 : SetEmphasisMark( rFont.GetEmphasisMark() );
640 7647 : SetKerning( rFont.IsKerning() );
641 7647 : SetOutline( rFont.IsOutline() );
642 7647 : SetShadow( rFont.IsShadow() );
643 7647 : SetRelief( rFont.GetRelief() );
644 7647 : }
645 :
646 1081795 : void Font::GetFontAttributes( ImplFontAttributes& rAttrs ) const
647 : {
648 1081795 : rAttrs.SetFamilyName( mpImplFont->maFamilyName );
649 1081795 : rAttrs.SetStyleName( mpImplFont->maStyleName );
650 1081795 : rAttrs.SetFamilyType( mpImplFont->meFamily );
651 1081795 : rAttrs.SetPitch( mpImplFont->mePitch );
652 1081795 : rAttrs.SetItalic( mpImplFont->meItalic );
653 1081795 : rAttrs.SetWeight( mpImplFont->meWeight );
654 1081795 : rAttrs.SetWidthType( WIDTH_DONTKNOW );
655 1081795 : rAttrs.SetSymbolFlag( mpImplFont->meCharSet == RTL_TEXTENCODING_SYMBOL );
656 1081795 : }
657 :
658 75586 : SvStream& ReadImpl_Font( SvStream& rIStm, Impl_Font& rImpl_Font )
659 : {
660 75586 : VersionCompat aCompat( rIStm, STREAM_READ );
661 : sal_uInt16 nTmp16;
662 : bool bTmp;
663 : sal_uInt8 nTmp8;
664 :
665 75586 : rImpl_Font.maFamilyName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
666 75586 : rImpl_Font.maStyleName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
667 75586 : ReadPair( rIStm, rImpl_Font.maSize );
668 :
669 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meCharSet = (rtl_TextEncoding) nTmp16;
670 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meFamily = (FontFamily) nTmp16;
671 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.mePitch = (FontPitch) nTmp16;
672 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meWeight = (FontWeight) nTmp16;
673 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meUnderline = (FontUnderline) nTmp16;
674 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meStrikeout = (FontStrikeout) nTmp16;
675 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meItalic = (FontItalic) nTmp16;
676 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.maLanguageTag.reset( (LanguageType) nTmp16);
677 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meWidthType = (FontWidth) nTmp16;
678 :
679 75586 : rIStm.ReadInt16( rImpl_Font.mnOrientation );
680 :
681 75586 : rIStm.ReadCharAsBool( bTmp ); rImpl_Font.mbWordLine = bTmp;
682 75586 : rIStm.ReadCharAsBool( bTmp ); rImpl_Font.mbOutline = bTmp;
683 75586 : rIStm.ReadCharAsBool( bTmp ); rImpl_Font.mbShadow = bTmp;
684 75586 : rIStm.ReadUChar( nTmp8 ); rImpl_Font.mnKerning = nTmp8;
685 :
686 75586 : if( aCompat.GetVersion() >= 2 )
687 : {
688 75586 : rIStm.ReadUChar( nTmp8 ); rImpl_Font.meRelief = (FontRelief)nTmp8;
689 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.maCJKLanguageTag.reset( (LanguageType)nTmp16);
690 75586 : rIStm.ReadCharAsBool( bTmp ); rImpl_Font.mbVertical = bTmp;
691 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meEmphasisMark = (FontEmphasisMark)nTmp16;
692 : }
693 75586 : if( aCompat.GetVersion() >= 3 )
694 : {
695 75586 : rIStm.ReadUInt16( nTmp16 ); rImpl_Font.meOverline = (FontUnderline) nTmp16;
696 : }
697 : // Relief
698 : // CJKContextLanguage
699 :
700 75586 : return rIStm;
701 : }
702 :
703 85426 : SvStream& WriteImpl_Font( SvStream& rOStm, const Impl_Font& rImpl_Font )
704 : {
705 85426 : VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
706 85426 : rOStm.WriteUniOrByteString( rImpl_Font.maFamilyName, rOStm.GetStreamCharSet() );
707 85426 : rOStm.WriteUniOrByteString( rImpl_Font.maStyleName, rOStm.GetStreamCharSet() );
708 85426 : WritePair( rOStm, rImpl_Font.maSize );
709 :
710 85426 : rOStm.WriteUInt16( GetStoreCharSet( rImpl_Font.meCharSet ) );
711 85426 : rOStm.WriteUInt16( rImpl_Font.meFamily );
712 85426 : rOStm.WriteUInt16( rImpl_Font.mePitch );
713 85426 : rOStm.WriteUInt16( rImpl_Font.meWeight );
714 85426 : rOStm.WriteUInt16( rImpl_Font.meUnderline );
715 85426 : rOStm.WriteUInt16( rImpl_Font.meStrikeout );
716 85426 : rOStm.WriteUInt16( rImpl_Font.meItalic );
717 85426 : rOStm.WriteUInt16( rImpl_Font.maLanguageTag.getLanguageType( false) );
718 85426 : rOStm.WriteUInt16( rImpl_Font.meWidthType );
719 :
720 85426 : rOStm.WriteInt16( rImpl_Font.mnOrientation );
721 :
722 85426 : rOStm.WriteUChar( rImpl_Font.mbWordLine );
723 85426 : rOStm.WriteUChar( rImpl_Font.mbOutline );
724 85426 : rOStm.WriteUChar( rImpl_Font.mbShadow );
725 85426 : rOStm.WriteUChar( rImpl_Font.mnKerning );
726 :
727 : // new in version 2
728 85426 : rOStm.WriteUChar( rImpl_Font.meRelief );
729 85426 : rOStm.WriteUInt16( rImpl_Font.maCJKLanguageTag.getLanguageType( false) );
730 85426 : rOStm.WriteUChar( rImpl_Font.mbVertical );
731 85426 : rOStm.WriteUInt16( rImpl_Font.meEmphasisMark );
732 :
733 : // new in version 3
734 85426 : rOStm.WriteUInt16( rImpl_Font.meOverline );
735 :
736 85426 : return rOStm;
737 : }
738 :
739 75586 : SvStream& ReadFont( SvStream& rIStm, ::vcl::Font& rFont )
740 : {
741 75586 : rFont.MakeUnique();
742 75586 : return ReadImpl_Font( rIStm, *rFont.mpImplFont );
743 : }
744 :
745 85426 : SvStream& WriteFont( SvStream& rOStm, const ::vcl::Font& rFont )
746 : {
747 85426 : return WriteImpl_Font( rOStm, *rFont.mpImplFont );
748 : }
749 :
750 : namespace
751 : {
752 0 : bool identifyTrueTypeFont( const void* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
753 : {
754 0 : bool bResult = false;
755 0 : TrueTypeFont* pTTF = NULL;
756 0 : if( OpenTTFontBuffer( const_cast<void*>(i_pBuffer), i_nSize, 0, &pTTF ) == SF_OK )
757 : {
758 : TTGlobalFontInfo aInfo;
759 0 : GetTTGlobalFontInfo( pTTF, &aInfo );
760 : // most importantly: the family name
761 0 : if( aInfo.ufamily )
762 0 : o_rResult.SetName( aInfo.ufamily );
763 0 : else if( aInfo.family )
764 0 : o_rResult.SetName( OStringToOUString( aInfo.family, RTL_TEXTENCODING_ASCII_US ) );
765 : // set weight
766 0 : if( aInfo.weight )
767 : {
768 0 : if( aInfo.weight < FW_EXTRALIGHT )
769 0 : o_rResult.SetWeight( WEIGHT_THIN );
770 0 : else if( aInfo.weight < FW_LIGHT )
771 0 : o_rResult.SetWeight( WEIGHT_ULTRALIGHT );
772 0 : else if( aInfo.weight < FW_NORMAL )
773 0 : o_rResult.SetWeight( WEIGHT_LIGHT );
774 0 : else if( aInfo.weight < FW_MEDIUM )
775 0 : o_rResult.SetWeight( WEIGHT_NORMAL );
776 0 : else if( aInfo.weight < FW_SEMIBOLD )
777 0 : o_rResult.SetWeight( WEIGHT_MEDIUM );
778 0 : else if( aInfo.weight < FW_BOLD )
779 0 : o_rResult.SetWeight( WEIGHT_SEMIBOLD );
780 0 : else if( aInfo.weight < FW_EXTRABOLD )
781 0 : o_rResult.SetWeight( WEIGHT_BOLD );
782 0 : else if( aInfo.weight < FW_BLACK )
783 0 : o_rResult.SetWeight( WEIGHT_ULTRABOLD );
784 : else
785 0 : o_rResult.SetWeight( WEIGHT_BLACK );
786 : }
787 : else
788 0 : o_rResult.SetWeight( (aInfo.macStyle & 1) ? WEIGHT_BOLD : WEIGHT_NORMAL );
789 : // set width
790 0 : if( aInfo.width )
791 : {
792 0 : if( aInfo.width == FWIDTH_ULTRA_CONDENSED )
793 0 : o_rResult.SetWidth( WIDTH_ULTRA_CONDENSED );
794 0 : else if( aInfo.width == FWIDTH_EXTRA_CONDENSED )
795 0 : o_rResult.SetWidth( WIDTH_EXTRA_CONDENSED );
796 0 : else if( aInfo.width == FWIDTH_CONDENSED )
797 0 : o_rResult.SetWidth( WIDTH_CONDENSED );
798 0 : else if( aInfo.width == FWIDTH_SEMI_CONDENSED )
799 0 : o_rResult.SetWidth( WIDTH_SEMI_CONDENSED );
800 0 : else if( aInfo.width == FWIDTH_NORMAL )
801 0 : o_rResult.SetWidth( WIDTH_NORMAL );
802 0 : else if( aInfo.width == FWIDTH_SEMI_EXPANDED )
803 0 : o_rResult.SetWidth( WIDTH_SEMI_EXPANDED );
804 0 : else if( aInfo.width == FWIDTH_EXPANDED )
805 0 : o_rResult.SetWidth( WIDTH_EXPANDED );
806 0 : else if( aInfo.width == FWIDTH_EXTRA_EXPANDED )
807 0 : o_rResult.SetWidth( WIDTH_EXTRA_EXPANDED );
808 0 : else if( aInfo.width >= FWIDTH_ULTRA_EXPANDED )
809 0 : o_rResult.SetWidth( WIDTH_ULTRA_EXPANDED );
810 : }
811 : // set italic
812 0 : o_rResult.SetItalic( (aInfo.italicAngle != 0) ? ITALIC_NORMAL : ITALIC_NONE );
813 :
814 : // set pitch
815 0 : o_rResult.SetPitch( (aInfo.pitch == 0) ? PITCH_VARIABLE : PITCH_FIXED );
816 :
817 : // set style name
818 0 : if( aInfo.usubfamily )
819 0 : o_rResult.SetStyleName( OUString( aInfo.usubfamily ) );
820 0 : else if( aInfo.subfamily )
821 0 : o_rResult.SetStyleName( OUString::createFromAscii( aInfo.subfamily ) );
822 :
823 : // cleanup
824 0 : CloseTTFont( pTTF );
825 : // success
826 0 : bResult = true;
827 : }
828 0 : return bResult;
829 : }
830 :
831 : struct WeightSearchEntry
832 : {
833 : const char* string;
834 : int string_len;
835 : FontWeight weight;
836 :
837 0 : bool operator<( const WeightSearchEntry& rRight ) const
838 : {
839 0 : return rtl_str_compareIgnoreAsciiCase_WithLength( string, string_len, rRight.string, rRight.string_len ) < 0;
840 : }
841 : }
842 : weight_table[] =
843 : {
844 : { "black", 5, WEIGHT_BLACK },
845 : { "bold", 4, WEIGHT_BOLD },
846 : { "book", 4, WEIGHT_LIGHT },
847 : { "demi", 4, WEIGHT_SEMIBOLD },
848 : { "heavy", 5, WEIGHT_BLACK },
849 : { "light", 5, WEIGHT_LIGHT },
850 : { "medium", 6, WEIGHT_MEDIUM },
851 : { "regular", 7, WEIGHT_NORMAL },
852 : { "super", 5, WEIGHT_ULTRABOLD },
853 : { "thin", 4, WEIGHT_THIN }
854 : };
855 :
856 0 : bool identifyType1Font( const char* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
857 : {
858 0 : bool bResult = false;
859 : // might be a type1, find eexec
860 0 : const char* pStream = i_pBuffer;
861 0 : const char* pExec = "eexec";
862 0 : const char* pExecPos = std::search( pStream, pStream+i_nSize, pExec, pExec+5 );
863 0 : if( pExecPos != pStream+i_nSize)
864 : {
865 : // find /FamilyName entry
866 : static const char* pFam = "/FamilyName";
867 0 : const char* pFamPos = std::search( pStream, pExecPos, pFam, pFam+11 );
868 0 : if( pFamPos != pExecPos )
869 : {
870 : // extract the string value behind /FamilyName
871 0 : const char* pOpen = pFamPos+11;
872 0 : while( pOpen < pExecPos && *pOpen != '(' )
873 0 : pOpen++;
874 0 : const char* pClose = pOpen;
875 0 : while( pClose < pExecPos && *pClose != ')' )
876 0 : pClose++;
877 0 : if( pClose - pOpen > 1 )
878 : {
879 0 : o_rResult.SetName( OStringToOUString( OString( pOpen+1, pClose-pOpen-1 ), RTL_TEXTENCODING_ASCII_US ) );
880 : }
881 : }
882 :
883 : // parse /ItalicAngle
884 : static const char* pItalic = "/ItalicAngle";
885 0 : const char* pItalicPos = std::search( pStream, pExecPos, pItalic, pItalic+12 );
886 0 : if( pItalicPos != pExecPos )
887 : {
888 0 : sal_Int32 nItalic = rtl_str_toInt32( pItalicPos+12, 10 );
889 0 : o_rResult.SetItalic( (nItalic != 0) ? ITALIC_NORMAL : ITALIC_NONE );
890 : }
891 :
892 : // parse /Weight
893 : static const char* pWeight = "/Weight";
894 0 : const char* pWeightPos = std::search( pStream, pExecPos, pWeight, pWeight+7 );
895 0 : if( pWeightPos != pExecPos )
896 : {
897 : // extract the string value behind /Weight
898 0 : const char* pOpen = pWeightPos+7;
899 0 : while( pOpen < pExecPos && *pOpen != '(' )
900 0 : pOpen++;
901 0 : const char* pClose = pOpen;
902 0 : while( pClose < pExecPos && *pClose != ')' )
903 0 : pClose++;
904 0 : if( pClose - pOpen > 1 )
905 : {
906 : WeightSearchEntry aEnt;
907 0 : aEnt.string = pOpen+1;
908 0 : aEnt.string_len = (pClose-pOpen)-1;
909 0 : aEnt.weight = WEIGHT_NORMAL;
910 0 : const int nEnt = SAL_N_ELEMENTS( weight_table );
911 0 : WeightSearchEntry* pFound = std::lower_bound( weight_table, weight_table+nEnt, aEnt );
912 0 : if( pFound != (weight_table+nEnt) )
913 0 : o_rResult.SetWeight( pFound->weight );
914 : }
915 : }
916 :
917 : // parse isFixedPitch
918 : static const char* pFixed = "/isFixedPitch";
919 0 : const char* pFixedPos = std::search( pStream, pExecPos, pFixed, pFixed+13 );
920 0 : if( pFixedPos != pExecPos )
921 : {
922 : // skip whitespace
923 0 : while( pFixedPos < pExecPos-4 &&
924 0 : ( *pFixedPos == ' ' ||
925 0 : *pFixedPos == '\t' ||
926 0 : *pFixedPos == '\r' ||
927 0 : *pFixedPos == '\n' ) )
928 : {
929 0 : pFixedPos++;
930 : }
931 : // find "true" value
932 0 : if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos, 4, "true", 4 ) == 0 )
933 0 : o_rResult.SetPitch( PITCH_FIXED );
934 : else
935 0 : o_rResult.SetPitch( PITCH_VARIABLE );
936 : }
937 : }
938 0 : return bResult;
939 : }
940 : }
941 :
942 0 : Font Font::identifyFont( const void* i_pBuffer, sal_uInt32 i_nSize )
943 : {
944 0 : Font aResult;
945 0 : if( ! identifyTrueTypeFont( i_pBuffer, i_nSize, aResult ) )
946 : {
947 0 : const char* pStream = reinterpret_cast<const char*>(i_pBuffer);
948 0 : if( pStream && i_nSize > 100 &&
949 0 : *pStream == '%' && pStream[1] == '!' )
950 : {
951 0 : identifyType1Font( pStream, i_nSize, aResult );
952 : }
953 : }
954 :
955 0 : return aResult;
956 : }
957 :
958 : // The inlines from the font.hxx header are now instantiated for pImpl-ification
959 3429470 : const Color& Font::GetColor() const { return mpImplFont->maColor; }
960 :
961 168396 : const Color& Font::GetFillColor() const { return mpImplFont->maFillColor; }
962 :
963 840256 : bool Font::IsTransparent() const { return mpImplFont->mbTransparent; }
964 :
965 1832045 : FontAlign Font::GetAlign() const { return mpImplFont->meAlign; }
966 :
967 4684573 : const OUString& Font::GetName() const { return mpImplFont->maFamilyName; }
968 :
969 159122 : const OUString& Font::GetStyleName() const { return mpImplFont->maStyleName; }
970 :
971 4152517 : const Size& Font::GetSize() const { return mpImplFont->maSize; }
972 :
973 320297 : void Font::SetHeight( long nHeight ) { SetSize( Size( mpImplFont->maSize.Width(), nHeight ) ); }
974 :
975 964571 : long Font::GetHeight() const { return mpImplFont->maSize.Height(); }
976 :
977 0 : void Font::SetWidth( long nWidth ) { SetSize( Size( nWidth, mpImplFont->maSize.Height() ) ); }
978 :
979 0 : long Font::GetWidth() const { return mpImplFont->maSize.Width(); }
980 :
981 739592 : rtl_TextEncoding Font::GetCharSet() const { return mpImplFont->meCharSet; }
982 :
983 2163326 : const LanguageTag& Font::GetLanguageTag() const { return mpImplFont->maLanguageTag; }
984 :
985 7583 : const LanguageTag& Font::GetCJKContextLanguageTag() const { return mpImplFont->maCJKLanguageTag; }
986 :
987 3531489 : LanguageType Font::GetLanguage() const { return mpImplFont->maLanguageTag.getLanguageType( false); }
988 :
989 10252 : LanguageType Font::GetCJKContextLanguage() const { return mpImplFont->maCJKLanguageTag.getLanguageType( false); }
990 :
991 2288040 : short Font::GetOrientation() const { return mpImplFont->mnOrientation; }
992 :
993 3281226 : bool Font::IsVertical() const { return mpImplFont->mbVertical; }
994 :
995 4736674 : FontKerning Font::GetKerning() const { return mpImplFont->mnKerning; }
996 :
997 105896 : FontPitch Font::GetPitch() const { return mpImplFont->GetPitch(); }
998 :
999 1652947 : FontWeight Font::GetWeight() const { return mpImplFont->GetWeight(); }
1000 :
1001 6929 : FontWidth Font::GetWidthType() const { return mpImplFont->GetWidthType(); }
1002 :
1003 8417477 : FontItalic Font::GetItalic() const { return mpImplFont->GetItalic(); }
1004 :
1005 85548 : FontFamily Font::GetFamily() const { return mpImplFont->GetFamily(); }
1006 :
1007 897209 : bool Font::IsOutline() const { return mpImplFont->mbOutline; }
1008 :
1009 925670 : bool Font::IsShadow() const { return mpImplFont->mbShadow; }
1010 :
1011 998289 : FontRelief Font::GetRelief() const { return mpImplFont->meRelief; }
1012 :
1013 3306593 : FontUnderline Font::GetUnderline() const { return mpImplFont->meUnderline; }
1014 :
1015 1769970 : FontUnderline Font::GetOverline() const { return mpImplFont->meOverline; }
1016 :
1017 1765401 : FontStrikeout Font::GetStrikeout() const { return mpImplFont->meStrikeout; }
1018 :
1019 1335110 : FontEmphasisMark Font::GetEmphasisMark() const { return mpImplFont->meEmphasisMark; }
1020 :
1021 2356767 : bool Font::IsWordLineMode() const { return mpImplFont->mbWordLine; }
1022 :
1023 3621208 : bool Font::IsSameInstance( const vcl::Font& rFont ) const { return (mpImplFont == rFont.mpImplFont); }
1024 :
1025 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|