1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
19 #include "fontmetrics.h"
20 #include "strrefdup.h"
23 FontMetrics::CharacterMetrics::~CharacterMetrics( )
25 if( ligatureSetupMap_
!= 0 )
27 delete ligatureSetupMap_
;
32 FontMetrics::CharacterMetrics::isEmpty( ) const
34 return xmax_
== 0 && ymax_
== 0&& xmin_
== 0 && ymin_
== 0;
38 FontMetrics::CharacterMetrics::hasLigature( size_t otherInternalPosition
, size_t * ligatureInternalPosition
) const
40 typedef typeof( ligatures_
) MapType
;
41 MapType::const_iterator i
= ligatures_
.find( otherInternalPosition
);
42 if( i
== ligatures_
.end( ) )
46 *ligatureInternalPosition
= i
->second
;
51 FontMetrics::CharacterMetrics::addLigature( RefCountPtr
< const char > otherName
, RefCountPtr
< const char > ligatureName
)
53 typedef typeof( *ligatureSetupMap_
) MapType
;
54 if( ligatureSetupMap_
== 0 )
56 ligatureSetupMap_
= new MapType
;;
58 ligatureSetupMap_
->insert( MapType::value_type( otherName
, ligatureName
) );
62 FontMetrics::CharacterMetrics::setupLigatures( const std::map
< RefCountPtr
< const char >, size_t, charRefPtrLess
> & nameMap
) const
64 if( ligatureSetupMap_
== 0 )
69 typedef typeof( *ligatureSetupMap_
) MapType
;
70 typedef typeof( nameMap
) NameMapType
;
71 for( MapType::const_iterator i
= ligatureSetupMap_
->begin( ); i
!= ligatureSetupMap_
->end( ); ++i
)
73 NameMapType::const_iterator iFirst
= nameMap
.find( i
->first
);
74 NameMapType::const_iterator iSecond
= nameMap
.find( i
->second
);
75 if( iFirst
== nameMap
.end( ) || iSecond
== nameMap
.end( ) )
77 throw strrefdup( "Font metrics ligature uses undefined character name." );
79 ligatures_
[ iFirst
->second
] = iSecond
->second
;
82 delete ligatureSetupMap_
;
83 ligatureSetupMap_
= 0;
87 FontMetrics::CharacterMetrics::display( std::ostream
& os
) const
89 os
<< "[" << internalPosition_
<< "] "
90 << " C " << characterCode_
<< ";"
91 << " W0 " << horizontalCharWidthX_
<< " " << horizontalCharWidthY_
<< ";"
92 << " B " << xmin_
<< " " << ymin_
<< " " << xmax_
<< " " << ymax_
<< ";" ;
95 FontMetrics::WritingDirectionMetrics::WritingDirectionMetrics( )
97 // charData_ begins with a default entry. This makes it possible to use 0 for "undefined" in codeMap_.
98 FontMetrics::CharacterMetrics
* defaultChar
= new FontMetrics::CharacterMetrics( charData_
.size( ) );
99 charData_
.push_back( defaultChar
);
100 // The values of defaultChar are not set here, since we need both horizontal and vertical information for that.
102 codeMap_
.resize( 256, 0 );
105 FontMetrics::WritingDirectionMetrics::~WritingDirectionMetrics( )
109 FontMetrics::WritingDirectionMetrics::setupLigatures( )
111 typedef typeof( charData_
) ListType
;
112 for( ListType::iterator i
= charData_
.begin( ); i
!= charData_
.end( ); ++i
)
114 (*i
)->setupLigatures( nameMap_
);
118 const FontMetrics::CharacterMetrics
*
119 FontMetrics::WritingDirectionMetrics::charByName( const char * name
) const
121 typedef typeof( nameMap_
) NameMapType
;
122 NameMapType::const_iterator i
= nameMap_
.find( strrefdup( name
) );
123 if( i
== nameMap_
.end( ) )
125 throw "No character by that name in font metrics.";
127 return charData_
[ i
->second
];
130 const FontMetrics::CharacterMetrics
*
131 FontMetrics::WritingDirectionMetrics::charByCode( unsigned char code
) const
133 return charData_
[ codeMap_
[ code
] ];
136 const FontMetrics::CharacterMetrics
*
137 FontMetrics::WritingDirectionMetrics::charByCode( char code
) const
139 throw "WritingDirectionMetrics::charByCode called with signed argument type.";
143 FontMetrics::WritingDirectionMetrics::display( std::ostream
& os
) const
145 typedef typeof( nameMap_
) NameMapType
;
146 for( NameMapType::const_iterator i
= nameMap_
.begin( ); i
!= nameMap_
.end( ); ++i
)
148 os
<< "\"" << i
->first
<< "\" " ;
149 charData_
[ i
->second
]->display( os
);
154 FontMetrics::TrackKerning::TrackKerning( double sizeLow
, double trackLow
, double sizeHigh
, double trackHigh
)
155 : sizeLow_( sizeLow
), trackLow_( trackLow
), sizeHigh_( sizeHigh
), trackHigh_( trackHigh
)
159 FontMetrics::TrackKerning::operator () ( double sz
) const
169 return trackLow_
+ ( ( sz
- sizeLow_
) / ( sizeHigh_
- sizeLow_
) ) * ( trackHigh_
- trackLow_
);
173 FontMetrics::AFM::~AFM( )
177 FontMetrics::AFM::getHorizontalKernPairXByCode( unsigned char code1
, unsigned char code2
) const
179 KernPairMap::const_iterator i
= horizontalKernPairsX_
.find( KernPairMap::key_type( horizontalMetrics_
->codeMap_
[ code1
], horizontalMetrics_
->codeMap_
[ code2
] ) );
180 if( i
== horizontalKernPairsX_
.end( ) )
188 FontMetrics::AFM::getHorizontalKernPairXByCode( char code1
, char code2
) const
190 throw "AFM::getHorizontalKernPairXByCode called with signed argument type.";
193 FontMetrics::BaseFont::~BaseFont( )