source: trunk/src/kernel/qfont_pm.cpp

Last change on this file was 174, checked in by dmik, 18 years ago

Styles: Implemented the first version of the Warp4 style (contributed by Cornelis Bockemuehl).

  • Property svn:keywords set to Id
File size: 11.9 KB
Line 
1/****************************************************************************
2** $Id: qfont_pm.cpp 174 2007-11-06 22:27:57Z dmik $
3**
4** Implementation of QFont, QFontMetrics and QFontInfo classes for OS/2
5**
6** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
7** Copyright (C) 2004 Norman ASA. Initial OS/2 Port.
8** Copyright (C) 2005 netlabs.org. Further OS/2 Development.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qfont.h"
39#include "qfontdata_p.h"
40#include "qfontengine_p.h"
41#include "qfontmetrics.h"
42#include "qfontinfo.h"
43
44#include "qwidget.h"
45#include "qpainter.h"
46#include "qdict.h"
47#include "qcache.h"
48#include <limits.h>
49#include "qt_os2.h"
50#include "qapplication_p.h"
51#include "qapplication.h"
52#include "qpaintdevicemetrics.h"
53#include <private/qunicodetables_p.h>
54#include <qfontdatabase.h>
55
56
57QString qt_pm_default_family( uint styleHint )
58{
59 switch( styleHint ) {
60 case QFont::Times:
61 return QString::fromLatin1( "Times New Roman" );
62 case QFont::Courier:
63 return QString::fromLatin1( "Courier" );
64 case QFont::Decorative:
65 return QString::fromLatin1( "Times New Roman" );
66 case QFont::Helvetica:
67 return QString::fromLatin1( "Helvetica" );
68 case QFont::System: {
69#ifndef QT_PM_NO_DEFAULTFONT_OVERRIDE
70 static ULONG ver[2] = {0};
71 if ( ver[0] == ver[1] == 0 ) {
72 DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MINOR,
73 &ver, sizeof(ver) );
74 }
75 if ( ver[0] == 20 && ver[1] >= 40 )
76 return QString::fromLatin1( "WarpSans" );
77 else
78#endif
79 return QString::fromLatin1( "System Proportional" );
80 }
81 default:
82 // the family to be used when no StyleHint is set (in accordance
83 // with the font matching algorithm stated in QFont docs)
84 return QString::fromLatin1( "Helvetica" );
85 }
86//@@TODO (dmik): should we also add default font substitutions to
87// initFontSubst()?
88}
89
90/*****************************************************************************
91 QFont member functions
92 *****************************************************************************/
93
94QFont::Script QFontPrivate::defaultScript = QFont::UnknownScript;
95
96void QFont::initialize()
97{
98 if ( QFontCache::instance )
99 return;
100 new QFontCache();
101
102 // #########
103 QFontPrivate::defaultScript = QFont::Latin;
104}
105
106void QFont::cleanup()
107{
108 delete QFontCache::instance;
109}
110
111void QFontPrivate::load( QFont::Script script )
112{
113 // NOTE: the OS/2 implementation of this function is similar to
114 // X11 and Windows implementations (which are identical). if they
115 // change, probably, changes should come here as well...
116
117#ifdef QT_CHECK_STATE
118 // sanity checks
119 if (!QFontCache::instance)
120 qWarning("Must construct a QApplication before a QFont");
121 Q_ASSERT( script >= 0 && script < QFont::LastPrivateScript );
122#endif // QT_CHECK_STATE
123
124 QFontDef req = request;
125 int dpi;
126 if ( paintdevice ) {
127 dpi = QPaintDeviceMetrics( paintdevice ).logicalDpiY();
128 } else {
129 DevQueryCaps( GpiQueryDevice( qt_display_ps() ),
130 CAPS_VERTICAL_FONT_RES, 1, (PLONG) &dpi );
131 }
132 if (req.pointSize != -1)
133 req.pixelSize = (req.pointSize * dpi + 360) / 720;
134 else // assuming (req.pixelSize != -1)
135 req.pointSize = 0;
136
137 if ( ! engineData ) {
138 QFontCache::Key key( req, QFont::NoScript, (int)paintdevice );
139
140 // look for the requested font in the engine data cache
141 engineData = QFontCache::instance->findEngineData( key );
142
143 if ( ! engineData) {
144 // create a new one
145 engineData = new QFontEngineData;
146 QFontCache::instance->insertEngineData( key, engineData );
147 } else {
148 engineData->ref();
149 }
150 }
151
152 // the cached engineData could have already loaded the engine we want
153//@@TODO (dmik): remove?
154// if ( engineData->engines[script] ) return;
155 if ( engineData->engine ) return;
156
157 // load the font
158 QFontEngine *engine = 0;
159 // double scale = 1.0; // ### TODO: fix the scale calculations
160
161 // list of families to try
162 QStringList family_list;
163
164 if (!req.family.isEmpty()) {
165 family_list = QStringList::split( ',', req.family );
166
167 // append the substitute list for each family in family_list
168 QStringList subs_list;
169 QStringList::ConstIterator it = family_list.begin(), end = family_list.end();
170 for ( ; it != end; ++it )
171 subs_list += QFont::substitutes( *it );
172 family_list += subs_list;
173
174//@@TODO (dmik): need something here?
175 // append the default fallback font for the specified script
176 // family_list << ... ; ###########
177
178 // add the family corresponding to font's styleHint
179 QString hintFamily = qt_pm_default_family( request.styleHint );
180 if ( ! family_list.contains( hintFamily ) )
181 family_list << hintFamily;
182
183//@@TODO (dmik): should we also add QFont::lastResortFamily() and
184// QFont::lastResortFont() to the list as stated in QFont docs about the
185// font matching algorithm? Also it's not clear why QApplication font is
186// below added to the list.
187
188 // add the default family
189 QString defaultFamily = QApplication::font().family();
190 if ( ! family_list.contains( defaultFamily ) )
191 family_list << defaultFamily;
192
193 // add QFont::defaultFamily() to the list, for compatibility with
194 // previous versions
195 family_list << QApplication::font().defaultFamily();
196 }
197
198 // null family means find the first font matching the specified script
199 family_list << QString::null;
200
201 QStringList::ConstIterator it = family_list.begin(), end = family_list.end();
202 for ( ; ! engine && it != end; ++it ) {
203 req.family = *it;
204
205 engine = QFontDatabase::findFont( script, this, req );
206 if ( engine ) {
207 if ( engine->type() != QFontEngine::Box )
208 break;
209
210 if ( ! req.family.isEmpty() )
211 engine = 0;
212
213 continue;
214 }
215 }
216
217 engine->ref();
218//@@TODO (dmik): remove?
219// engineData->engines[script] = engine;
220 engineData->engine = engine;
221}
222
223//@@TODO (dmik): do we actually need any handle?
224//PFATTRS QFont::handle() const
225//{
226// QFontEngine *engine = d->engineForScript( QFont::NoScript );
227// return &engine->fa;
228//}
229
230void QFont::selectTo( HPS hps ) const
231{
232 QFontEngine *engine = d->engineForScript( QFont::NoScript );
233#ifdef QT_CHECK_STATE
234 Q_ASSERT( engine != 0 );
235#endif // QT_CHECK_STATE
236 engine->selectTo( hps );
237}
238
239QString QFont::rawName() const
240{
241//@@TODO (dmik): use szFacename here?
242 return family();
243}
244
245void QFont::setRawName( const QString &name )
246{
247 setFamily( name );
248}
249
250
251bool QFont::dirty() const
252{
253 return !d->engineData;
254}
255
256
257QString QFont::defaultFamily() const
258{
259 return qt_pm_default_family( d->request.styleHint );
260}
261
262QString QFont::lastResortFamily() const
263{
264 return qt_pm_default_family( QFont::AnyStyle );
265}
266
267QString QFont::lastResortFont() const
268{
269 return QString::fromLatin1( "System Proportional" );
270}
271
272
273
274/*****************************************************************************
275 QFontMetrics member functions
276 *****************************************************************************/
277
278//@@TODO (dmik): do we need a separate (other than in qfont.cpp)
279// implementation of this func?
280//int QFontMetrics::leftBearing(QChar ch) const
281//{
282//#ifdef Q_OS_TEMP
283// return 0;
284//#else
285// QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
286//#ifdef QT_CHECK_STATE
287// Q_ASSERT( engine != 0 );
288//#endif // QT_CHECK_STATE
289//
290// if ( IS_TRUETYPE ) {
291// ABC abc;
292// QT_WA( {
293// uint ch16 = ch.unicode();
294// GetCharABCWidths(engine->dc(),ch16,ch16,&abc);
295// } , {
296// uint ch8;
297// if ( ch.row() || ch.cell() > 127 ) {
298// QCString w = QString(ch).local8Bit();
299// if ( w.length() != 1 )
300// return 0;
301// ch8 = (uchar)w[0];
302// } else {
303// ch8 = ch.cell();
304// }
305// GetCharABCWidthsA(engine->dc(),ch8,ch8,&abc);
306// } );
307// return abc.abcA;
308// } else {
309// QT_WA( {
310// uint ch16 = ch.unicode();
311// ABCFLOAT abc;
312// GetCharABCWidthsFloat(engine->dc(),ch16,ch16,&abc);
313// return int(abc.abcfA);
314// } , {
315// return 0;
316// } );
317// }
318// return 0;
319//#endif
320//}
321
322
323//@@TODO (dmik): do we need a separate (other than in qfont.cpp)
324// implementation of this func?
325//int QFontMetrics::rightBearing(QChar ch) const
326//{
327// return 0;
328//#ifdef Q_OS_TEMP
329// return 0;
330//#else
331// QFontEngine *engine = d->engineForScript( (QFont::Script) fscript );
332//#ifdef QT_CHECK_STATE
333// Q_ASSERT( engine != 0 );
334//#endif // QT_CHECK_STATE
335//
336// if ( IS_TRUETYPE ) {
337// ABC abc;
338// QT_WA( {
339// uint ch16 = ch.unicode();
340// GetCharABCWidths(engine->dc(),ch16,ch16,&abc);
341// return abc.abcC;
342// } , {
343// uint ch8;
344// if ( ch.row() || ch.cell() > 127 ) {
345// QCString w = QString(ch).local8Bit();
346// if ( w.length() != 1 )
347// return 0;
348// ch8 = (uchar)w[0];
349// } else {
350// ch8 = ch.cell();
351// }
352// GetCharABCWidthsA(engine->dc(),ch8,ch8,&abc);
353// } );
354// return abc.abcC;
355// } else {
356// QT_WA( {
357// uint ch16 = ch.unicode();
358// ABCFLOAT abc;
359// GetCharABCWidthsFloat(engine->dc(),ch16,ch16,&abc);
360// return int(abc.abcfC);
361// } , {
362// return -TMW.tmOverhang;
363// } );
364// }
365//
366// return 0;
367//#endif
368//}
369
370
371int QFontMetrics::width( QChar ch ) const
372{
373 if ( ::category( ch ) == QChar::Mark_NonSpacing )
374 return 0;
375
376 QFont::Script script;
377 SCRIPT_FOR_CHAR( script, ch );
378
379 QFontEngine *engine = d->engineForScript( script );
380#ifdef QT_CHECK_STATE
381 Q_ASSERT( engine != 0 );
382#endif // QT_CHECK_STATE
383
384 if ( painter )
385 painter->setNativeXForm( FALSE /* assumeYNegation */);
386
387 glyph_t glyphs[8];
388 advance_t advances[8];
389
390 int nglyphs = 7;
391 engine->stringToCMap( &ch, 1, glyphs, advances, &nglyphs, FALSE );
392
393 if ( painter )
394 painter->clearNativeXForm();
395
396 return advances[0];
397}
398
399
400int QFontMetrics::charWidth( const QString &str, int pos ) const
401{
402 if ( pos < 0 || pos > (int)str.length() )
403 return 0;
404
405 if ( painter )
406 painter->setNativeXForm( FALSE /* assumeYNegation */);
407
408 QTextEngine layout( str, d );
409 layout.itemize( QTextEngine::WidthOnly );
410 int w = layout.width( pos, 1 );
411
412 if ( painter )
413 painter->clearNativeXForm();
414
415 return w;
416}
Note: See TracBrowser for help on using the repository browser.