2005-06-24 07:31:41 +04:00
|
|
|
/*
|
|
|
|
* Copyright 2001-2005, Haiku.
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* DarkWyrm <bpmagic@columbus.rr.com>
|
2005-10-20 13:39:12 +04:00
|
|
|
* Jérôme Duval, jerome.duval@free.fr
|
2005-06-24 07:31:41 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2005-05-12 19:09:30 +04:00
|
|
|
#include <ByteOrder.h>
|
2005-04-01 11:00:32 +04:00
|
|
|
#include <Shape.h>
|
2005-06-03 23:50:30 +04:00
|
|
|
#include <String.h>
|
2005-05-12 19:09:30 +04:00
|
|
|
#include <UTF8.h>
|
|
|
|
|
2005-04-01 11:00:32 +04:00
|
|
|
#include "Angle.h"
|
2005-11-02 16:25:39 +03:00
|
|
|
#include "FontManager.h"
|
2005-05-12 19:09:30 +04:00
|
|
|
#include "moreUTF8.h"
|
2005-06-03 23:50:30 +04:00
|
|
|
#include "truncate_string.h"
|
2005-05-12 19:09:30 +04:00
|
|
|
|
2005-04-01 11:00:32 +04:00
|
|
|
#include FT_FREETYPE_H
|
2005-11-10 20:32:35 +03:00
|
|
|
#include FT_GLYPH_H
|
2005-04-01 11:00:32 +04:00
|
|
|
#include FT_OUTLINE_H
|
2003-01-01 01:19:48 +03:00
|
|
|
|
2005-05-12 19:09:30 +04:00
|
|
|
#include "ServerFont.h"
|
|
|
|
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
// functions needed to convert a freetype vector graphics to a BShape
|
|
|
|
inline BPoint
|
|
|
|
VectorToPoint(FT_Vector *vector)
|
|
|
|
{
|
|
|
|
BPoint result;
|
2006-02-05 01:20:00 +03:00
|
|
|
result.x = float(vector->x) / 64;
|
|
|
|
result.y = -float(vector->y) / 64;
|
2005-06-24 07:31:41 +04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
int
|
|
|
|
MoveToFunc(FT_Vector *to, void *user)
|
|
|
|
{
|
|
|
|
((BShape *)user)->MoveTo(VectorToPoint(to));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
int
|
|
|
|
LineToFunc(FT_Vector *to, void *user)
|
|
|
|
{
|
|
|
|
((BShape *)user)->LineTo(VectorToPoint(to));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
int
|
|
|
|
ConicToFunc(FT_Vector *control, FT_Vector *to, void *user)
|
|
|
|
{
|
|
|
|
BPoint controls[3];
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
controls[0] = VectorToPoint(control);
|
|
|
|
controls[1] = VectorToPoint(to);
|
|
|
|
controls[2] = controls[1];
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
((BShape *)user)->BezierTo(controls);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
int
|
|
|
|
CubicToFunc(FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *user)
|
|
|
|
{
|
|
|
|
BPoint controls[3];
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
controls[0] = VectorToPoint(control1);
|
|
|
|
controls[1] = VectorToPoint(control2);
|
|
|
|
controls[2] = VectorToPoint(to);
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
((BShape *)user)->BezierTo(controls);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
is_white_space(uint16 glyph)
|
|
|
|
{
|
|
|
|
// TODO: handle them all!
|
|
|
|
if (glyph == ' ' || glyph == B_TAB)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
class FaceGetter {
|
|
|
|
public:
|
|
|
|
FaceGetter(FontStyle *style)
|
|
|
|
:
|
|
|
|
fStyle(style)
|
|
|
|
{
|
|
|
|
style->Lock();
|
|
|
|
}
|
|
|
|
|
|
|
|
~FaceGetter()
|
|
|
|
{
|
|
|
|
fStyle->Unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
FT_Face Face()
|
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
return fStyle->FreeTypeFace();
|
2005-10-27 20:33:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
FontStyle *fStyle;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
|
|
|
2003-01-01 01:19:48 +03:00
|
|
|
/*!
|
|
|
|
\brief Constructor
|
2003-01-20 02:04:58 +03:00
|
|
|
\param style Style object to which the ServerFont belongs
|
|
|
|
\param size Character size in points
|
|
|
|
\param rotation Rotation in degrees
|
|
|
|
\param shear Shear (slant) in degrees. 45 <= shear <= 135
|
|
|
|
\param flags Style flags as defined in <Font.h>
|
|
|
|
\param spacing String spacing flag as defined in <Font.h>
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
2005-11-03 16:10:28 +03:00
|
|
|
ServerFont::ServerFont(FontStyle& style, float size,
|
2005-06-03 23:50:30 +04:00
|
|
|
float rotation, float shear,
|
|
|
|
uint16 flags, uint8 spacing)
|
2005-11-03 16:10:28 +03:00
|
|
|
: fStyle(&style),
|
2005-06-03 23:50:30 +04:00
|
|
|
fSize(size),
|
|
|
|
fRotation(rotation),
|
|
|
|
fShear(shear),
|
|
|
|
fBounds(0, 0, 0, 0),
|
|
|
|
fFlags(flags),
|
|
|
|
fSpacing(spacing),
|
2005-11-09 23:10:40 +03:00
|
|
|
fDirection(style.Direction()),
|
|
|
|
fFace(style.Face()),
|
2005-06-03 23:50:30 +04:00
|
|
|
fEncoding(B_UNICODE_UTF8)
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
fStyle->Acquire();
|
2003-01-01 01:19:48 +03:00
|
|
|
}
|
|
|
|
|
2005-04-14 04:22:01 +04:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
ServerFont::ServerFont()
|
2005-11-03 16:10:28 +03:00
|
|
|
:
|
|
|
|
fStyle(NULL)
|
2003-10-05 21:51:13 +04:00
|
|
|
{
|
2005-11-09 22:16:25 +03:00
|
|
|
*this = *gFontManager->DefaultPlainFont();
|
2003-10-05 21:51:13 +04:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2003-01-01 01:19:48 +03:00
|
|
|
/*!
|
|
|
|
\brief Copy Constructor
|
2003-01-20 02:04:58 +03:00
|
|
|
\param font ServerFont to copy
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
|
|
|
ServerFont::ServerFont(const ServerFont &font)
|
2005-11-03 16:10:28 +03:00
|
|
|
:
|
|
|
|
fStyle(NULL)
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
*this = font;
|
2003-01-01 01:19:48 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2003-01-01 01:19:48 +03:00
|
|
|
/*!
|
2003-01-18 23:32:45 +03:00
|
|
|
\brief Removes itself as a dependency of its owning style.
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
2005-06-03 23:50:30 +04:00
|
|
|
ServerFont::~ServerFont()
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
fStyle->Release();
|
2003-01-01 01:19:48 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2003-09-15 23:09:13 +04:00
|
|
|
/*!
|
|
|
|
\brief Returns a copy of the specified font
|
|
|
|
\param The font to copy from.
|
|
|
|
\return A copy of the specified font
|
|
|
|
*/
|
2005-06-03 23:50:30 +04:00
|
|
|
ServerFont&
|
|
|
|
ServerFont::operator=(const ServerFont& font)
|
|
|
|
{
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
if (font.fStyle) {
|
|
|
|
fSize = font.fSize;
|
|
|
|
fRotation = font.fRotation;
|
|
|
|
fShear = font.fShear;
|
|
|
|
fFlags = font.fFlags;
|
|
|
|
fSpacing = font.fSpacing;
|
|
|
|
fEncoding = font.fEncoding;
|
|
|
|
fBounds = font.fBounds;
|
|
|
|
|
|
|
|
SetStyle(font.fStyle);
|
|
|
|
}
|
|
|
|
|
2003-09-15 23:09:13 +04:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2003-01-01 01:19:48 +03:00
|
|
|
/*!
|
|
|
|
\brief Returns the number of strikes in the font
|
|
|
|
\return The number of strikes in the font
|
|
|
|
*/
|
2005-06-03 23:50:30 +04:00
|
|
|
int32
|
|
|
|
ServerFont::CountTuned()
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
return fStyle->TunedCount();
|
2003-01-01 01:19:48 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2003-01-01 01:19:48 +03:00
|
|
|
/*!
|
2005-11-03 16:10:28 +03:00
|
|
|
\brief Returns the file format of the font.
|
|
|
|
\return Mostly B_TRUETYPE_WINDOWS :)
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
2005-06-03 23:50:30 +04:00
|
|
|
font_file_format
|
|
|
|
ServerFont::FileFormat()
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
return fStyle->FileFormat();
|
2003-01-01 01:19:48 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
const char*
|
2005-11-09 23:10:40 +03:00
|
|
|
ServerFont::Style() const
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
return fStyle->Name();
|
2003-01-01 01:19:48 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
const char*
|
2005-11-09 23:10:40 +03:00
|
|
|
ServerFont::Family() const
|
2005-01-17 05:05:50 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
return fStyle->Family()->Name();
|
2005-01-17 05:05:50 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-11-03 20:03:36 +03:00
|
|
|
void
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
ServerFont::SetStyle(FontStyle* style)
|
2005-11-03 20:03:36 +03:00
|
|
|
{
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
if (style && style != fStyle) {
|
2005-11-03 20:03:36 +03:00
|
|
|
// detach from old style
|
|
|
|
if (fStyle)
|
|
|
|
fStyle->Release();
|
|
|
|
|
|
|
|
// attach to new style
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
fStyle = style;
|
2005-11-09 23:10:40 +03:00
|
|
|
|
2005-11-03 20:03:36 +03:00
|
|
|
fStyle->Acquire();
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
|
|
|
|
fFace = fStyle->Face();
|
|
|
|
fDirection = fStyle->Direction();
|
2005-11-03 20:03:36 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
/*!
|
|
|
|
\brief Sets the ServerFont instance to whatever font is specified
|
|
|
|
\param familyID ID number of the family to set
|
|
|
|
\param styleID ID number of the style to set
|
|
|
|
\return B_OK if successful, B_ERROR if not
|
|
|
|
*/
|
|
|
|
status_t
|
|
|
|
ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
|
2005-01-17 05:05:50 +03:00
|
|
|
{
|
2005-06-03 23:50:30 +04:00
|
|
|
FontStyle* style = NULL;
|
|
|
|
|
2005-11-02 16:25:39 +03:00
|
|
|
if (gFontManager->Lock()) {
|
|
|
|
style = gFontManager->GetStyle(familyID, styleID);
|
2005-11-03 16:10:28 +03:00
|
|
|
if (style != NULL)
|
|
|
|
style->Acquire();
|
|
|
|
|
2005-11-02 16:25:39 +03:00
|
|
|
gFontManager->Unlock();
|
2005-06-03 23:50:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!style)
|
|
|
|
return B_ERROR;
|
|
|
|
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
SetStyle(style);
|
2005-11-03 16:10:28 +03:00
|
|
|
style->Release();
|
2005-06-03 23:50:30 +04:00
|
|
|
|
|
|
|
return B_OK;
|
2005-01-17 05:05:50 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
/*!
|
|
|
|
\brief Sets the ServerFont instance to whatever font is specified
|
|
|
|
\param fontID the combination of family and style ID numbers
|
|
|
|
\return B_OK if successful, B_ERROR if not
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
2005-06-03 23:50:30 +04:00
|
|
|
status_t
|
|
|
|
ServerFont::SetFamilyAndStyle(uint32 fontID)
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
2005-06-03 23:50:30 +04:00
|
|
|
uint16 style = fontID & 0xFFFF;
|
|
|
|
uint16 family = (fontID & 0xFFFF0000) >> 16;
|
2005-01-21 16:13:08 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
return SetFamilyAndStyle(family, style);
|
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-11-09 23:10:40 +03:00
|
|
|
void
|
|
|
|
ServerFont::SetFace(uint32 face)
|
|
|
|
{
|
|
|
|
// TODO: change font style as requested!
|
|
|
|
fFace = face;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
/*!
|
|
|
|
\brief Gets the ID values for the ServerFont instance in one shot
|
|
|
|
\return the combination of family and style ID numbers
|
|
|
|
*/
|
|
|
|
uint32
|
|
|
|
ServerFont::GetFamilyAndStyle(void) const
|
|
|
|
{
|
|
|
|
return (FamilyID() << 16) | StyleID();
|
2005-01-21 16:13:08 +03:00
|
|
|
}
|
|
|
|
|
2005-04-01 11:00:32 +04:00
|
|
|
|
|
|
|
BShape **
|
|
|
|
ServerFont::GetGlyphShapes(const char charArray[], int32 numChars) const
|
|
|
|
{
|
|
|
|
if (!charArray || numChars <= 0)
|
|
|
|
return NULL;
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-04-01 11:00:32 +04:00
|
|
|
FT_Outline_Funcs funcs;
|
|
|
|
funcs.move_to = MoveToFunc;
|
|
|
|
funcs.line_to = LineToFunc;
|
|
|
|
funcs.conic_to = ConicToFunc;
|
|
|
|
funcs.cubic_to = CubicToFunc;
|
2006-02-05 01:20:00 +03:00
|
|
|
funcs.shift = 0;
|
|
|
|
funcs.delta = 0;
|
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-04-01 11:00:32 +04:00
|
|
|
if (!face)
|
|
|
|
return NULL;
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-06-15 21:09:00 +04:00
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-05-12 19:09:30 +04:00
|
|
|
Angle rotation(fRotation);
|
|
|
|
Angle shear(fShear);
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-04-01 11:00:32 +04:00
|
|
|
// First, rotate
|
|
|
|
FT_Matrix rmatrix;
|
|
|
|
rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000);
|
|
|
|
rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000);
|
|
|
|
rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000);
|
|
|
|
rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000);
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-04-01 11:00:32 +04:00
|
|
|
// Next, shear
|
|
|
|
FT_Matrix smatrix;
|
|
|
|
smatrix.xx = (FT_Fixed)(0x10000);
|
|
|
|
smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000);
|
|
|
|
smatrix.yx = (FT_Fixed)(0);
|
|
|
|
smatrix.yy = (FT_Fixed)(0x10000);
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-04-01 11:00:32 +04:00
|
|
|
// Multiply togheter
|
|
|
|
FT_Matrix_Multiply(&rmatrix, &smatrix);
|
2006-02-05 05:03:09 +03:00
|
|
|
FT_Set_Transform(face, &smatrix, NULL);
|
2006-02-05 01:20:00 +03:00
|
|
|
|
|
|
|
BShape **shapes = new BShape *[numChars];
|
2005-04-01 11:00:32 +04:00
|
|
|
for (int i = 0; i < numChars; i++) {
|
|
|
|
shapes[i] = new BShape();
|
|
|
|
shapes[i]->Clear();
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2005-07-19 19:22:55 +04:00
|
|
|
// TODO : this is wrong (the nth char isn't charArray[i])
|
2005-04-01 11:00:32 +04:00
|
|
|
FT_Load_Char(face, charArray[i], FT_LOAD_NO_BITMAP);
|
|
|
|
FT_Outline outline = face->glyph->outline;
|
|
|
|
FT_Outline_Decompose(&outline, &funcs, shapes[i]);
|
|
|
|
shapes[i]->Close();
|
|
|
|
}
|
2006-02-05 01:20:00 +03:00
|
|
|
|
2006-02-05 05:03:09 +03:00
|
|
|
// Reset transformation
|
|
|
|
FT_Set_Transform(face, NULL, NULL);
|
2005-04-01 11:00:32 +04:00
|
|
|
return shapes;
|
|
|
|
}
|
|
|
|
|
2005-07-19 19:22:55 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
ServerFont::GetHasGlyphs(const char charArray[], int32 numChars, bool hasArray[]) const
|
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
if (!charArray || numChars <= 0 || !hasArray)
|
2005-07-19 19:22:55 +04:00
|
|
|
return;
|
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-08-24 01:47:41 +04:00
|
|
|
if (!face)
|
|
|
|
return;
|
2005-07-19 19:22:55 +04:00
|
|
|
|
2005-08-24 01:47:41 +04:00
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
|
|
|
|
|
|
|
// UTF8 handling...this can probably be smarter
|
|
|
|
// Here is what I do in the AGGTextRenderer to handle UTF8...
|
|
|
|
// It is probably highly inefficient, so it should be reviewed.
|
|
|
|
int32 numBytes = UTF8CountBytes(charArray, numChars);
|
|
|
|
int32 convertedLength = numBytes * 2;
|
|
|
|
char* convertedBuffer = new char[convertedLength];
|
|
|
|
|
|
|
|
int32 state = 0;
|
|
|
|
status_t ret;
|
|
|
|
if ((ret = convert_from_utf8(B_UNICODE_CONVERSION,
|
|
|
|
charArray, &numBytes,
|
|
|
|
convertedBuffer, &convertedLength,
|
|
|
|
&state, B_SUBSTITUTE)) >= B_OK
|
|
|
|
&& (ret = swap_data(B_INT16_TYPE, convertedBuffer, convertedLength,
|
|
|
|
B_SWAP_BENDIAN_TO_HOST)) >= B_OK) {
|
|
|
|
|
|
|
|
uint16* glyphIndex = (uint16*)convertedBuffer;
|
|
|
|
// just to be sure
|
|
|
|
numChars = min_c((uint32)numChars, convertedLength / sizeof(uint16));
|
|
|
|
|
|
|
|
for (int i = 0; i < numChars; i++) {
|
|
|
|
hasArray[i] = FT_Get_Char_Index(face, glyphIndex[i]) > 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete[] convertedBuffer;
|
2005-08-24 18:50:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ServerFont::GetEdges(const char charArray[], int32 numChars, edge_info edgeArray[]) const
|
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
if (!charArray || numChars <= 0 || !edgeArray)
|
2005-08-24 18:50:41 +04:00
|
|
|
return;
|
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-08-24 18:50:41 +04:00
|
|
|
if (!face)
|
|
|
|
return;
|
|
|
|
|
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
2005-08-24 01:47:41 +04:00
|
|
|
|
2005-08-24 18:50:41 +04:00
|
|
|
// UTF8 handling...this can probably be smarter
|
|
|
|
// Here is what I do in the AGGTextRenderer to handle UTF8...
|
|
|
|
// It is probably highly inefficient, so it should be reviewed.
|
|
|
|
int32 numBytes = UTF8CountBytes(charArray, numChars);
|
|
|
|
int32 convertedLength = numBytes * 2;
|
|
|
|
char* convertedBuffer = new char[convertedLength];
|
2005-08-24 01:47:41 +04:00
|
|
|
|
2005-08-24 18:50:41 +04:00
|
|
|
int32 state = 0;
|
|
|
|
status_t ret;
|
|
|
|
if ((ret = convert_from_utf8(B_UNICODE_CONVERSION,
|
|
|
|
charArray, &numBytes,
|
|
|
|
convertedBuffer, &convertedLength,
|
|
|
|
&state, B_SUBSTITUTE)) >= B_OK
|
|
|
|
&& (ret = swap_data(B_INT16_TYPE, convertedBuffer, convertedLength,
|
|
|
|
B_SWAP_BENDIAN_TO_HOST)) >= B_OK) {
|
|
|
|
|
|
|
|
uint16* glyphIndex = (uint16*)convertedBuffer;
|
|
|
|
// just to be sure
|
|
|
|
numChars = min_c((uint32)numChars, convertedLength / sizeof(uint16));
|
|
|
|
|
|
|
|
for (int i = 0; i < numChars; i++) {
|
|
|
|
FT_Load_Char(face, glyphIndex[i], FT_LOAD_NO_BITMAP);
|
|
|
|
if (face->glyph) {
|
|
|
|
edgeArray[i].left = float(face->glyph->metrics.horiBearingX /64) / fSize;
|
|
|
|
edgeArray[i].right = float((face->glyph->metrics.horiBearingX
|
|
|
|
+ face->glyph->metrics.width - face->glyph->metrics.horiAdvance)/64) /fSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete[] convertedBuffer;
|
2005-07-19 19:22:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-12 19:09:30 +04:00
|
|
|
BPoint*
|
2005-04-01 13:18:25 +04:00
|
|
|
ServerFont::GetEscapements(const char charArray[], int32 numChars,
|
2005-05-12 19:09:30 +04:00
|
|
|
BPoint offsetArray[]) const
|
2005-04-01 13:18:25 +04:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
if (!charArray || numChars <= 0 || !offsetArray)
|
2005-04-01 13:18:25 +04:00
|
|
|
return NULL;
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-04-01 13:18:25 +04:00
|
|
|
if (!face)
|
|
|
|
return NULL;
|
2005-10-27 20:33:35 +04:00
|
|
|
|
2005-06-15 21:09:00 +04:00
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-05-12 19:09:30 +04:00
|
|
|
Angle rotation(fRotation);
|
|
|
|
Angle shear(fShear);
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-04-01 13:18:25 +04:00
|
|
|
// First, rotate
|
|
|
|
FT_Matrix rmatrix;
|
|
|
|
rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000);
|
|
|
|
rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000);
|
|
|
|
rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000);
|
|
|
|
rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000);
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-04-01 13:18:25 +04:00
|
|
|
// Next, shear
|
|
|
|
FT_Matrix smatrix;
|
|
|
|
smatrix.xx = (FT_Fixed)(0x10000);
|
|
|
|
smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000);
|
|
|
|
smatrix.yx = (FT_Fixed)(0);
|
|
|
|
smatrix.yy = (FT_Fixed)(0x10000);
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-04-01 13:18:25 +04:00
|
|
|
// Multiply togheter
|
|
|
|
FT_Matrix_Multiply(&rmatrix, &smatrix);
|
2006-02-05 05:03:09 +03:00
|
|
|
FT_Set_Transform(face, &smatrix, NULL);
|
2005-05-12 19:09:30 +04:00
|
|
|
|
|
|
|
// TODO: handle UTF8... see below!!
|
2006-02-05 01:20:00 +03:00
|
|
|
BPoint *escapements = new BPoint[numChars];
|
2005-04-01 13:18:25 +04:00
|
|
|
for (int i = 0; i < numChars; i++) {
|
2005-07-19 19:22:55 +04:00
|
|
|
// TODO : this is wrong (the nth char isn't charArray[i])
|
2005-04-01 13:18:25 +04:00
|
|
|
FT_Load_Char(face, charArray[i], FT_LOAD_NO_BITMAP);
|
2006-02-05 05:03:09 +03:00
|
|
|
escapements[i].x = float(face->glyph->advance.x) / 64 / fSize;
|
|
|
|
escapements[i].y = -float(face->glyph->advance.y) / 64 / fSize;
|
2005-04-01 13:18:25 +04:00
|
|
|
escapements[i] += offsetArray[i];
|
|
|
|
}
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2006-02-05 05:03:09 +03:00
|
|
|
// Reset transformation
|
|
|
|
FT_Set_Transform(face, NULL, NULL);
|
2005-04-01 13:18:25 +04:00
|
|
|
return escapements;
|
|
|
|
}
|
|
|
|
|
2005-05-16 15:03:28 +04:00
|
|
|
|
2005-05-12 19:09:30 +04:00
|
|
|
bool
|
2005-11-02 16:14:03 +03:00
|
|
|
ServerFont::GetEscapements(const char charArray[], int32 numChars, int32 numBytes,
|
2005-05-12 19:09:30 +04:00
|
|
|
float widthArray[], escapement_delta delta) const
|
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
if (!charArray || numChars <= 0)
|
2005-05-12 19:09:30 +04:00
|
|
|
return false;
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-05-12 19:09:30 +04:00
|
|
|
if (!face)
|
|
|
|
return false;
|
|
|
|
|
2005-06-15 21:09:00 +04:00
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
2005-05-12 19:09:30 +04:00
|
|
|
|
|
|
|
// UTF8 handling...this can probably be smarter
|
|
|
|
// Here is what I do in the AGGTextRenderer to handle UTF8...
|
|
|
|
// It is probably highly inefficient, so it should be reviewed.
|
|
|
|
int32 convertedLength = numBytes * 2;
|
|
|
|
char* convertedBuffer = new char[convertedLength];
|
|
|
|
|
|
|
|
int32 state = 0;
|
|
|
|
status_t ret;
|
|
|
|
if ((ret = convert_from_utf8(B_UNICODE_CONVERSION,
|
|
|
|
charArray, &numBytes,
|
|
|
|
convertedBuffer, &convertedLength,
|
|
|
|
&state, B_SUBSTITUTE)) >= B_OK
|
|
|
|
&& (ret = swap_data(B_INT16_TYPE, convertedBuffer, convertedLength,
|
|
|
|
B_SWAP_BENDIAN_TO_HOST)) >= B_OK) {
|
|
|
|
|
|
|
|
uint16* glyphIndex = (uint16*)convertedBuffer;
|
|
|
|
// just to be sure
|
2005-06-15 21:09:00 +04:00
|
|
|
numChars = min_c((uint32)numChars, convertedLength / sizeof(uint16));
|
2005-05-12 19:09:30 +04:00
|
|
|
|
|
|
|
for (int i = 0; i < numChars; i++) {
|
|
|
|
FT_Load_Char(face, glyphIndex[i], FT_LOAD_NO_BITMAP);
|
2005-06-15 21:09:00 +04:00
|
|
|
if (face->glyph) {
|
|
|
|
widthArray[i] = ((float)face->glyph->metrics.horiAdvance / 64.0) / fSize;
|
|
|
|
widthArray[i] += is_white_space(glyphIndex[i]) ? delta.space : delta.nonspace;
|
|
|
|
}
|
2005-05-12 19:09:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
delete[] convertedBuffer;
|
|
|
|
|
|
|
|
return ret >= B_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-25 19:21:34 +04:00
|
|
|
|
|
|
|
bool
|
2005-11-03 03:04:18 +03:00
|
|
|
ServerFont::GetBoundingBoxesAsString(const char charArray[], int32 numChars,
|
|
|
|
BRect rectArray[], bool string_escapement, font_metric_mode mode,
|
|
|
|
escapement_delta delta)
|
2005-08-25 19:21:34 +04:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
if (!charArray || numChars <= 0 || !rectArray)
|
2005-08-25 19:21:34 +04:00
|
|
|
return false;
|
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-08-25 19:21:34 +04:00
|
|
|
if (!face)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
2005-08-26 19:02:53 +04:00
|
|
|
|
|
|
|
// UTF8 handling...this can probably be smarter
|
|
|
|
// Here is what I do in the AGGTextRenderer to handle UTF8...
|
|
|
|
// It is probably highly inefficient, so it should be reviewed.
|
|
|
|
int32 numBytes = UTF8CountBytes(charArray, numChars);
|
|
|
|
int32 convertedLength = numBytes * 2;
|
|
|
|
char* convertedBuffer = new char[convertedLength];
|
|
|
|
|
|
|
|
int32 state = 0;
|
|
|
|
status_t ret;
|
|
|
|
if ((ret = convert_from_utf8(B_UNICODE_CONVERSION,
|
|
|
|
charArray, &numBytes,
|
|
|
|
convertedBuffer, &convertedLength,
|
|
|
|
&state, B_SUBSTITUTE)) >= B_OK
|
|
|
|
&& (ret = swap_data(B_INT16_TYPE, convertedBuffer, convertedLength,
|
|
|
|
B_SWAP_BENDIAN_TO_HOST)) >= B_OK) {
|
|
|
|
|
|
|
|
uint16* glyphIndex = (uint16*)convertedBuffer;
|
|
|
|
// just to be sure
|
|
|
|
numChars = min_c((uint32)numChars, convertedLength / sizeof(uint16));
|
|
|
|
|
|
|
|
for (int i = 0; i < numChars; i++) {
|
2005-08-30 18:53:42 +04:00
|
|
|
if (string_escapement) {
|
|
|
|
if (i>0)
|
|
|
|
rectArray[i].OffsetBy(is_white_space(glyphIndex[i-1]) ? delta.space/2.0 : delta.nonspace/2.0, 0.0);
|
|
|
|
rectArray[i].OffsetBy(is_white_space(glyphIndex[i]) ? delta.space/2.0 : delta.nonspace/2.0, 0.0);
|
|
|
|
}
|
2005-08-26 19:02:53 +04:00
|
|
|
FT_Load_Char(face, glyphIndex[i], FT_LOAD_NO_BITMAP);
|
|
|
|
if (face->glyph) {
|
2005-08-30 18:53:42 +04:00
|
|
|
if (i<numChars-1)
|
|
|
|
rectArray[i+1].left = rectArray[i+1].right = rectArray[i].left +
|
|
|
|
face->glyph->metrics.horiAdvance / 64.0;
|
|
|
|
rectArray[i].left += float(face->glyph->metrics.horiBearingX) /64.0;
|
|
|
|
rectArray[i].right += float(face->glyph->metrics.horiBearingX
|
2005-08-26 19:02:53 +04:00
|
|
|
+ face->glyph->metrics.width)/64.0;
|
|
|
|
rectArray[i].top = -float(face->glyph->metrics.horiBearingY) /64.0;
|
|
|
|
rectArray[i].bottom = float(face->glyph->metrics.height
|
|
|
|
- face->glyph->metrics.horiBearingY) /64.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete[] convertedBuffer;
|
2005-08-25 19:21:34 +04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
2005-08-26 19:02:53 +04:00
|
|
|
ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
|
2005-08-25 19:21:34 +04:00
|
|
|
int32 numStrings, BRect rectArray[], font_metric_mode mode, escapement_delta deltaArray[])
|
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
if (!charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray)
|
2005-08-25 19:21:34 +04:00
|
|
|
return false;
|
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-08-25 19:21:34 +04:00
|
|
|
if (!face)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
|
|
|
|
2005-11-03 03:04:18 +03:00
|
|
|
for (int32 i = 0; i < numStrings; i++) {
|
2005-11-02 16:14:03 +03:00
|
|
|
// TODO: ...
|
2005-08-26 19:02:53 +04:00
|
|
|
}
|
|
|
|
|
2005-08-25 19:21:34 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-20 21:36:55 +04:00
|
|
|
float
|
2005-05-21 03:51:33 +04:00
|
|
|
ServerFont::StringWidth(const char* string, int32 numBytes) const
|
2005-05-20 21:36:55 +04:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
if (!string || numBytes <= 0)
|
2005-05-21 03:51:33 +04:00
|
|
|
return 0.0;
|
2005-05-20 21:36:55 +04:00
|
|
|
|
2005-10-27 20:33:35 +04:00
|
|
|
FaceGetter getter(fStyle);
|
|
|
|
FT_Face face = getter.Face();
|
2005-05-21 03:51:33 +04:00
|
|
|
if (!face)
|
|
|
|
return 0.0;
|
2005-05-20 21:36:55 +04:00
|
|
|
|
2005-11-03 03:04:18 +03:00
|
|
|
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
|
2005-05-20 21:36:55 +04:00
|
|
|
|
2005-05-21 03:51:33 +04:00
|
|
|
int32 convertedLength = numBytes * 2;
|
|
|
|
char* convertedBuffer = new char[convertedLength];
|
2005-11-03 03:04:18 +03:00
|
|
|
float width = 0.0;
|
2005-05-21 03:51:33 +04:00
|
|
|
|
|
|
|
int32 state = 0;
|
|
|
|
status_t ret;
|
|
|
|
if ((ret = convert_from_utf8(B_UNICODE_CONVERSION,
|
|
|
|
string, &numBytes,
|
|
|
|
convertedBuffer, &convertedLength,
|
|
|
|
&state, B_SUBSTITUTE)) >= B_OK
|
|
|
|
&& (ret = swap_data(B_INT16_TYPE, convertedBuffer, convertedLength,
|
|
|
|
B_SWAP_BENDIAN_TO_HOST)) >= B_OK) {
|
|
|
|
|
|
|
|
uint16* glyphIndex = (uint16*)convertedBuffer;
|
|
|
|
// just to be sure
|
|
|
|
int numChars = convertedLength / sizeof(uint16);
|
|
|
|
|
|
|
|
for (int i = 0; i < numChars; i++) {
|
|
|
|
FT_Load_Char(face, glyphIndex[i], FT_LOAD_NO_BITMAP);
|
2005-11-03 03:04:18 +03:00
|
|
|
width += face->glyph->advance.x / 64.0;
|
2005-05-21 03:51:33 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
delete[] convertedBuffer;
|
2005-05-20 21:36:55 +04:00
|
|
|
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
/*!
|
|
|
|
\brief Returns a BRect which encloses the entire font
|
|
|
|
\return A BRect which encloses the entire font
|
2005-02-05 23:12:05 +03:00
|
|
|
*/
|
2005-06-03 23:50:30 +04:00
|
|
|
BRect
|
|
|
|
ServerFont::BoundingBox()
|
2005-02-05 23:12:05 +03:00
|
|
|
{
|
2005-06-03 23:50:30 +04:00
|
|
|
// TODO: fBounds is nowhere calculated!
|
|
|
|
return fBounds;
|
2005-02-05 23:12:05 +03:00
|
|
|
}
|
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
/*!
|
|
|
|
\brief Obtains the height values for characters in the font in its current state
|
|
|
|
\param fh pointer to a font_height object to receive the values for the font
|
2005-01-21 16:13:08 +03:00
|
|
|
*/
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
2005-11-03 16:10:28 +03:00
|
|
|
ServerFont::GetHeight(font_height& height) const
|
2005-01-21 16:13:08 +03:00
|
|
|
{
|
2005-11-03 16:10:28 +03:00
|
|
|
fStyle->GetHeight(fSize, height);
|
2003-01-01 01:19:48 +03:00
|
|
|
}
|
2005-01-23 16:40:11 +03:00
|
|
|
|
2005-11-03 16:10:28 +03:00
|
|
|
|
2005-06-03 23:50:30 +04:00
|
|
|
void
|
|
|
|
ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const
|
2005-01-23 16:40:11 +03:00
|
|
|
{
|
2005-06-03 23:50:30 +04:00
|
|
|
if (inOut) {
|
|
|
|
// the width of the "…" glyph
|
|
|
|
float ellipsisWidth = StringWidth(B_UTF8_ELLIPSIS, 3);
|
|
|
|
const char* string = inOut->String();
|
|
|
|
int32 length = strlen(string);
|
|
|
|
// temporary array to hold result
|
|
|
|
char* result = new char[length + 3];
|
|
|
|
// count the individual glyphs
|
|
|
|
int32 numChars = UTF8CountChars(string, length);
|
|
|
|
// get the escapement of each glyph in font units
|
|
|
|
float* escapementArray = new float[numChars];
|
|
|
|
static escapement_delta delta = (escapement_delta){ 0.0, 0.0 };
|
2005-11-02 16:14:03 +03:00
|
|
|
GetEscapements(string, numChars, length, escapementArray, delta);
|
2005-06-03 23:50:30 +04:00
|
|
|
|
|
|
|
truncate_string(string, mode, width, result,
|
|
|
|
escapementArray, fSize, ellipsisWidth, length, numChars);
|
|
|
|
|
|
|
|
inOut->SetTo(result);
|
|
|
|
|
|
|
|
delete[] escapementArray;
|
|
|
|
delete[] result;
|
|
|
|
}
|
2005-01-23 16:40:11 +03:00
|
|
|
}
|
|
|
|
|