6c5a58d665da25962fe7688aaaef0a885ba892c3
[occt.git] / src / Aspect / Aspect_FontStyle.cxx
1 // Created on: 1993-09-14
2 // Created by: GG       
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //GG_040298     eliminer les variables statiques globales.
18
19 #define PRO5676 //GG_020197
20 //              Donner la possibillite d'exprimer la taille
21 //              par rapport a la hauteur totale du caractere ou par
22 //              rapport a la hauteur "ascent" situee au dessus de la 
23 //              ligne de base.
24 //              (CapsHeight flag)
25
26 //GG_160498 etude G1343 gerer les polices transformables pour 
27 //          l'utilisation de MFT_FontManager.
28
29 // =====================================================================
30 // DCB_120598 study S3553. Platform specific code has been deleted
31 // ("#ifdef WNT") to be able to use on WNT the same font descriptor
32 // string like on UNIX.
33 // =====================================================================
34
35
36
37 //-Version      
38
39 //-Design       Declaration des variables specifiques aux Fontures de textes
40
41 //-Warning      Un style est definie, soit par son type predefini TOF_...
42 //              soit par sa description (Font string de type ADOBE) 
43
44 //-References   
45
46 //-Language     C++ 2.0
47
48 //-Declarations
49 #define MAXFIELDS 14
50 #define PITCHSIZE (0.00028 METER);
51
52 // for the class
53 #include <Aspect_FontStyle.ixx>
54 #include <Aspect_Units.hxx>
55 #include <stdio.h>
56
57 //-Aliases
58
59 //-Global data definitions
60
61 //      MyFontType      :       TypeOfFont from Aspect;
62 //      MyStyle         :       AsciiString from  TCollection
63 //      MyFontName      :       AsciiCString from TCollection 
64 //      MyFontSize      :       Real from Standard
65 //      MyFontSlant     :       Real from Standard
66 //      MyCapsHeight    :       Boolean from Standard
67
68 //-Constructors
69
70 //-Destructors
71
72 //-Methods, in order
73
74 Aspect_FontStyle::Aspect_FontStyle () {
75
76         SetPredefinedStyle(Aspect_TOF_DEFAULT,0.003 METER,0.,Standard_False) ;
77 }
78
79 Aspect_FontStyle::Aspect_FontStyle (const Aspect_TypeOfFont Type, const Quantity_Length Size, const Quantity_PlaneAngle Slant, const Standard_Boolean CapsHeight) {
80
81         SetPredefinedStyle(Type,Size,Slant,CapsHeight) ;
82 }
83
84 Aspect_FontStyle::Aspect_FontStyle (const Standard_CString style, const Quantity_Length Size, const Quantity_PlaneAngle Slant, const Standard_Boolean CapsHeight) {
85
86         MyFontType = Aspect_TOF_USERDEFINED ;
87         MyFontSize = Size;
88         MyFontSlant = Slant;
89         MyCapsHeight = CapsHeight;
90         MyStyle = style;
91         MyFontName = Normalize(style,MyFontSize) ;
92 }
93
94 Aspect_FontStyle::Aspect_FontStyle (const Standard_CString style) {
95
96         MyFontType = Aspect_TOF_USERDEFINED ;
97         MyFontSize = 0. ;
98         MyFontSlant = 0. ;
99         MyCapsHeight = Standard_False;
100         MyStyle = style;
101         MyFontName = Normalize(style,MyFontSize) ;
102 }
103
104 Aspect_FontStyle& Aspect_FontStyle::Assign (const Aspect_FontStyle& Other) {
105
106         MyFontType = Other.Style() ;
107         MyFontSize = Other.Size() ;
108         MyFontSlant = Other.Slant() ;
109         MyStyle = Other.Value();
110         MyFontName = Other.FullName() ;
111         MyCapsHeight = Other.CapsHeight() ;
112
113         return (*this);
114 }
115
116 void Aspect_FontStyle::SetValues ( const Aspect_TypeOfFont Type, const Quantity_Length Size, const Quantity_PlaneAngle Slant, const Standard_Boolean CapsHeight) {
117
118         SetPredefinedStyle (Type,Size,Slant,CapsHeight);
119 }
120
121 void Aspect_FontStyle::SetValues ( const Standard_CString style, const Quantity_Length Size, const Quantity_PlaneAngle Slant, const Standard_Boolean CapsHeight) {
122         MyFontType = Aspect_TOF_USERDEFINED ;
123         MyFontSize = Size;
124         MyFontSlant = Slant;
125         MyCapsHeight = CapsHeight;
126         MyStyle = style;
127         MyFontName = Normalize(style,MyFontSize) ;
128 }
129
130 void Aspect_FontStyle::SetValues ( const Standard_CString style) {
131         MyFontType = Aspect_TOF_USERDEFINED ;
132         MyFontSize = 0. ;
133         MyFontSlant = 0. ;
134         MyCapsHeight = Standard_False;
135         MyStyle = style;
136         MyFontName = Normalize(style,MyFontSize) ;
137 }
138
139 // ============================================================================
140 //        ---Purpose: Sets the family of the font.
141 // ============================================================================
142
143 void Aspect_FontStyle::SetFamily(const Standard_CString aName) {
144     MyFontName = SetField(MyFontName,aName,2);
145 }
146
147 // ============================================================================
148 //        ---Purpose: Sets the weight of the font.
149 // ============================================================================
150
151 void Aspect_FontStyle::SetWeight(const Standard_CString aName) {
152     MyFontName = SetField(MyFontName,aName,3);
153 }
154
155 // ============================================================================
156 //        ---Purpose: Sets the Registry of the font.
157 // ============================================================================
158
159 void Aspect_FontStyle::SetRegistry(const Standard_CString aName) {
160     MyFontName = SetField(MyFontName,aName,13);
161 }
162
163 // ============================================================================
164 //        ---Purpose: Sets the Encoding of the font.
165 // ============================================================================
166
167 void Aspect_FontStyle::SetEncoding(const Standard_CString aName) {
168     MyFontName = SetField(MyFontName,aName,14);
169 }
170
171 Aspect_TypeOfFont Aspect_FontStyle::Style () const {
172
173         return (MyFontType);
174 }
175
176 Standard_Integer Aspect_FontStyle::Length () const {
177
178         return MyStyle.Length();
179 }
180
181 Standard_CString Aspect_FontStyle::Value () const
182 {
183   return MyStyle.ToCString();
184 }
185
186 Quantity_Length Aspect_FontStyle::Size () const {
187         return (MyFontSize);
188 }
189
190 Quantity_PlaneAngle Aspect_FontStyle::Slant () const {
191
192         return (MyFontSlant);
193 }
194
195 Standard_Boolean Aspect_FontStyle::CapsHeight () const {
196
197         return (MyCapsHeight);
198 }
199
200 // ============================================================================
201 //        ---Purpose: Returns the alias font name.
202 //        --          this is a shorter font name which identify the
203 //        --          main characteristics of the fonts.
204 //        ---Example: "helvetica-bold"
205 // ============================================================================
206
207 Standard_CString Aspect_FontStyle::AliasName() const
208 {
209 static TCollection_AsciiString aliasname;
210     aliasname.Clear();
211     TCollection_AsciiString family(Family());
212     if( family.Length() > 0 && family != "*" ) {
213       TCollection_AsciiString FAMILY = family; FAMILY.UpperCase();
214       family.SetValue(1,FAMILY.Value(1));
215       aliasname = family; 
216     }
217     TCollection_AsciiString weight(Weight()); 
218     if( weight.Length() > 0 && weight != "*" ) {
219       TCollection_AsciiString WEIGHT = weight; WEIGHT.UpperCase();
220       if( WEIGHT == "NORMAL" ) {
221         weight.Clear();
222       } else {
223         weight.SetValue(1,WEIGHT.Value(1));
224       }
225     } else weight.Clear();
226     TCollection_AsciiString sslant(SSlant());
227     if( sslant.Length() > 0 && sslant != "*" ) {
228       if( sslant == "r" ) {
229         sslant.Clear();
230       } else if( sslant == "i" ) {
231         weight += "Italic";
232         sslant.Clear();
233       } else if( sslant == "o" ) {
234         weight += "Oblique";
235         sslant.Clear();
236       }
237     } else sslant.Clear();
238     if( weight.Length() > 0 ) {
239       aliasname += '-'; aliasname += weight;
240     }
241     if( sslant.Length() > 0 ) {
242       aliasname += '-'; aliasname += sslant;
243     }
244     TCollection_AsciiString swidth(SWidth());
245     if( swidth.Length() > 0 && swidth != "*" ) {
246       TCollection_AsciiString SWIDTH = swidth; SWIDTH.UpperCase();
247       if( SWIDTH == "NORMAL" ) {
248       } else {
249         if( !weight.Length() ) aliasname += '-';
250         aliasname += '-'; aliasname += swidth;
251       }
252     }
253     return aliasname.ToCString();
254 }
255 // ============================================================================
256 //        ---Purpose: Returns the full normalized font name
257 // ============================================================================
258
259 Standard_CString Aspect_FontStyle::FullName () const {
260
261         return (MyFontName.ToCString());
262 }
263
264 // ============================================================================
265 //        ---Purpose: Returns the foundry of the font.
266 //        ---Example: "adobe"
267 // ============================================================================
268
269 Standard_CString Aspect_FontStyle::Foundry() const
270 {
271     return Field(MyFontName,1);
272 }
273
274 // ============================================================================
275 //        ---Purpose: Returns the family of the font.
276 //        ---Example: "helvetica"
277 // ============================================================================
278
279 Standard_CString Aspect_FontStyle::Family() const
280 {
281     return Field(MyFontName,2);
282 }
283
284 // ============================================================================
285 //        ---Purpose: Returns the weight of the font.
286 //        ---Example: "bold"
287 // ============================================================================
288
289 Standard_CString Aspect_FontStyle::Weight() const
290 {
291     return Field(MyFontName,3);
292 }
293
294 // ============================================================================
295 //        ---Purpose: Returns the char set registry of the font.
296 //        ---Example: "iso8859"
297 // ============================================================================
298
299 Standard_CString Aspect_FontStyle::Registry() const
300 {
301     return Field(MyFontName,13);
302 }
303
304 // ============================================================================
305 //        ---Purpose: Returns the char set encoding of the font.
306 //        ---Example: "1"
307 // ============================================================================
308
309 Standard_CString Aspect_FontStyle::Encoding() const
310 {
311     return Field(MyFontName,14);
312 }
313
314 // ============================================================================
315 //        ---Purpose: Returns the slant of the font.
316 //        ---Example: "i"
317 // ============================================================================
318
319 Standard_CString Aspect_FontStyle::SSlant() const
320 {
321     return Field(MyFontName,4);
322 }
323
324 // ============================================================================
325 //        ---Purpose: Returns the width name of the font.
326 //        ---Example: "normal"
327 // ============================================================================
328
329 Standard_CString Aspect_FontStyle::SWidth() const
330 {
331     return Field(MyFontName,5);
332 }
333
334 // ============================================================================
335 //        ---Purpose: Returns the style name of the font.
336 //        ---Example: "serif"
337 // ============================================================================
338
339 Standard_CString Aspect_FontStyle::SStyle() const
340 {
341     return Field(MyFontName,6);
342 }
343
344 // ============================================================================
345 //        ---Purpose: Returns the pixel size of the font.
346 //        ---Example: "14"
347 // ============================================================================
348
349 Standard_CString Aspect_FontStyle::SPixelSize() const
350 {
351     return Field(MyFontName,7);
352 }
353
354 // ============================================================================
355 //        ---Purpose: Returns the point size of the font.
356 //        ---Example: "140"
357 // ============================================================================
358
359 Standard_CString Aspect_FontStyle::SPointSize() const
360 {
361     return Field(MyFontName,8);
362 }
363 // ============================================================================
364 //        ---Purpose: Returns the resolution X of the font.
365 //        ---Example: "75"
366 // ============================================================================
367
368 Standard_CString Aspect_FontStyle::SResolutionX() const
369 {
370     return Field(MyFontName,9);
371 }
372
373 // ============================================================================
374 //        ---Purpose: Returns the resolution Y of the font.
375 //        ---Example: "75"
376 // ============================================================================
377
378 Standard_CString Aspect_FontStyle::SResolutionY() const
379 {
380     return Field(MyFontName,10);
381 }
382
383 // ============================================================================
384 //        ---Purpose: Returns the spacing of the font.
385 //        ---Example: "p"
386 // ============================================================================
387
388 Standard_CString Aspect_FontStyle::SSpacing() const
389 {
390     return Field(MyFontName,11);
391 }
392
393 // ============================================================================
394 //        ---Purpose: Returns the average width of the font.
395 //        ---Example: "90"
396 // ============================================================================
397
398 Standard_CString Aspect_FontStyle::SAverageWidth() const
399 {
400     return Field(MyFontName,12);
401 }
402
403 // ============================================================================
404 //        ---Purpose: Dumps the font attributes.
405 // ============================================================================
406
407 void Aspect_FontStyle::Dump() const
408 {
409     cout << ".Aspect_FontStyle::Dump() :" << endl;
410     cout << "-----------------" << endl << endl;
411     cout << "  style name is : '" << this->Value() << "'" << endl;
412     cout << "  Normalized font name is : '" << this->FullName() << "'" << endl;
413     cout << "  Alias font name is : '" << this->AliasName() << "'" << endl;
414     cout << "    Foundry is : '" << this->Foundry() << "'" << endl;
415     cout << "    Family is : '" << this->Family() << "'" << endl;
416     cout << "    Weight is : '" << this->Weight() << "'" << endl;
417     cout << "    Slant is : '" << this->SSlant() << "'" << endl;
418     cout << "    Width is : '" << this->SWidth() << "'" << endl;
419     cout << "    Style is : '" << this->SStyle() << "'" << endl;
420     cout << "    PixelSize is : '" << this->SPixelSize() << "'" << endl;
421     cout << "    PointSize is : '" << this->SPointSize() << "'" << endl;
422     cout << "    ResolutionX is : '" << this->SResolutionX() << "'" << endl;
423     cout << "    ResolutionY is : '" << this->SResolutionY() << "'" << endl;
424     cout << "    Spacing is : '" << this->SSpacing() << "'" << endl;
425     cout << "    AverageWidth is : '" << this->SAverageWidth() << "'" << endl;
426     cout << "    Registry is : '" << this->Registry() << "'" << endl;
427     cout << "    Encoding is : '" << this->Encoding() << "'" << endl << endl;
428 }
429
430 void Aspect_FontStyle::SetPredefinedStyle( const Aspect_TypeOfFont Type, const Quantity_Length Size, const Quantity_PlaneAngle Slant, const Standard_Boolean CapsHeight) {
431
432         if( Size <= 0. )
433                 Aspect_FontStyleDefinitionError::Raise ("Bad font Size");
434
435         MyFontType = Type ;
436         MyFontSize = Size;
437         MyFontSlant = Slant ;
438         MyCapsHeight = CapsHeight;
439         Standard_CString pstyle = "" ;
440         switch ( Type ) {
441             case Aspect_TOF_USERDEFINED :
442                 Aspect_FontStyleDefinitionError::Raise ("Bad Font Type Style");
443             case Aspect_TOF_DEFAULT :
444                 pstyle = "Defaultfont" ;
445                 break ;
446             case Aspect_TOF_COURIER :
447                 pstyle = "Courier" ;
448                 break ;
449             case Aspect_TOF_HELVETICA :
450                 pstyle = "Helvetica" ;
451                 break ;
452             case Aspect_TOF_TIMES :
453                 pstyle = "Times" ;
454                 break ;
455         }
456         MyStyle = pstyle;
457         MyFontName = Normalize(pstyle,MyFontSize);
458 }
459
460 Standard_Boolean Aspect_FontStyle::IsEqual(const Aspect_FontStyle& Other) const
461 {
462   return (
463           (MyFontType == Other.MyFontType) &&
464           (MyFontName.Length() == Other.MyFontName.Length()) &&
465           (MyFontName == Other.MyFontName) &&
466           (MyFontSize == Other.MyFontSize) &&
467           (MyFontSlant == Other.MyFontSlant) &&
468           (MyCapsHeight == Other.MyCapsHeight)
469          );
470
471 }
472
473 Standard_Boolean Aspect_FontStyle::IsNotEqual(const Aspect_FontStyle& Other) const
474 {
475   return !IsEqual(Other);
476 }
477
478 // ============================================================================
479 //        ---Purpose: Returns a normalized XLFD descriptor from the font name
480 //        --         <aFontName>
481 // ============================================================================
482
483 Standard_CString Aspect_FontStyle::Normalize(const Standard_CString aFontName,Standard_Real& aSize)
484 {
485     Aspect_FontStyleDefinitionError_Raise_if( 
486                                 !aFontName ,"NULL font descriptor");
487
488 static TCollection_AsciiString afontstring;
489 static TCollection_AsciiString astar("*");
490 static TCollection_AsciiString azero("0");
491 TCollection_AsciiString afield,afontname(aFontName);
492 Standard_CString pfontname = NULL;
493 Standard_Boolean xlfd = Standard_False;
494 Standard_Integer i,len = afontname.Length();
495
496     afontstring = "";
497
498     if( len <= 0 ) return pfontname;
499
500     if( afontname.Value(1) != '-' ) afontname.Prepend("-adobe-");
501     for( i=1 ; i<=MAXFIELDS ; i++ ) {
502       Standard_CString pfield = Field(afontname,i);
503       switch (i) {
504         case 1:
505           if( pfield ) {
506             afield = pfield; afield.LowerCase();
507             {afontstring += '-'; afontstring += afield;}
508           } else {
509             afontstring += "-adobe";
510           }
511           break;
512         case 7:
513           if( pfield ) {
514             afield = pfield; afield.LowerCase();
515             if( afield == astar ) {
516               if( aSize > 0. ) afontstring += "-*";
517               else {afontstring += "-0"; xlfd = Standard_True;}
518             } else if( afield == azero ) { afontstring += "-0"; xlfd = Standard_True;}
519             else {afontstring += '-'; afontstring += afield;}
520           } else {
521             if( aSize > 0. ) afontstring += "-*";
522             else { afontstring += "-0"; xlfd = Standard_True;}
523           }
524           break;
525         case 8:
526         case 9:
527         case 10:
528           if( xlfd ) {
529             afontstring += "-0";
530           } else if( pfield ) {
531             afield = pfield; afield.LowerCase();
532             afontstring += '-'; afontstring += afield;
533           } else {
534             afontstring += "-*";
535           }
536           break;
537         case 13:
538           if( pfield ) {
539             afield = pfield; afield.LowerCase();
540             afontstring += '-'; afontstring += afield;
541           } else {
542             afontstring += "-*";
543           }
544           break;
545         default:
546           if( pfield ) {
547             afield = pfield;
548             afontstring += '-'; afontstring += afield;
549           } else {
550             afontstring += "-*";
551           }
552       }
553     }
554     pfontname = afontstring.ToCString();
555     if( aSize == 0. ) {
556       Standard_CString psize = Field(pfontname,7);
557       Standard_Integer isize;
558       if( sscanf(psize,"%d",&isize) == 1 ) {
559         aSize = isize*PITCHSIZE;
560       } else {
561         aSize = 2. MILLIMETER;
562       }
563     }
564
565     return pfontname;
566 }
567
568 // ============================================================================
569 //        ---Purpose: Returns the field at position <aRank>
570 //        --          from the font name <aFontName>.
571 // ============================================================================
572
573 Standard_CString Aspect_FontStyle::Field(const TCollection_AsciiString& aFontName,const Standard_Integer aRank)
574 {
575 static TCollection_AsciiString afieldstring;
576 Standard_Integer length = aFontName.Length();
577 Standard_CString pfield = NULL;
578
579     if( length > 0 && aRank >= 1 && aRank <= MAXFIELDS ) {
580       Standard_Integer start = 1,end = 0;
581       start = aFontName.Location(aRank,'-',1,length);
582       end = aFontName.Location(aRank+1,'-',1,length);
583       afieldstring = "";
584       if( start > 0 && end > 0 ) {
585         start++ ; 
586         end--;
587         if( end >= start ) afieldstring = aFontName.SubString(start,end);
588         else afieldstring = "";
589       } else if( start > 0 ) {
590         start++ ; 
591         end = length;
592         if( end >= start ) afieldstring = aFontName.SubString(start,end);
593         else afieldstring = "";
594       } else {
595         return NULL;
596       }
597     }
598     pfield = afieldstring.ToCString();
599
600     return pfield;
601 }
602
603 // ============================================================================
604 //        ---Purpose: Sets the field at position <aRank>
605 //        --          of the font <aFontName>
606 //        --          from the field <aField>.
607 // ============================================================================
608
609 Standard_CString Aspect_FontStyle::SetField(const TCollection_AsciiString& aFontName,const Standard_CString aField,const Standard_Integer aRank)
610 {
611 static TCollection_AsciiString afontstring;
612 Standard_Integer length = aFontName.Length();
613 Standard_CString pfontname = NULL;
614
615     if( length > 0 && aRank >= 1 && aRank <= MAXFIELDS ) {
616       Standard_Integer start = 1,end = 0;
617       start = aFontName.Location(aRank,'-',1,length);
618       end = aFontName.Location(aRank+1,'-',1,length);
619       TCollection_AsciiString lowername(""),uppername(""); 
620       if( start > 0 && end > 0 ) {
621         if( end > start ) {
622           if( start > 1 ) lowername = aFontName.SubString(1,start);
623           uppername = aFontName.SubString(end,length);
624         }
625       } else if( start > 1 ) {
626         lowername = aFontName.SubString(1,start);
627       } else {
628         return NULL;
629       }
630       afontstring = lowername;
631       afontstring += aField; afontstring += uppername;
632       pfontname = afontstring.ToCString();
633     }
634
635     return pfontname;
636 }