#include "apricot.h"
#include "Drawable.h"
#include "private/Drawable.h"
#ifdef __cplusplus
extern
"C"
{
#endif
void
Drawable_clear_font_abc_caches( Handle self)
{
PList u;
if
(( u = var-> font_abc_glyphs)) {
int
i;
for
( i = 0; i < u-> count; i += 2)
free
((
void
*) u-> items[ i + 1]);
plist_destroy( u);
var-> font_abc_glyphs = NULL;
}
if
(( u = var-> font_abc_unicode)) {
int
i;
for
( i = 0; i < u-> count; i += 2)
free
((
void
*) u-> items[ i + 1]);
plist_destroy( u);
var-> font_abc_unicode = NULL;
}
if
( var-> font_abc_ascii) {
free
( var-> font_abc_ascii);
var-> font_abc_ascii = NULL;
}
if
( var-> font_abc_glyphs_ranges ) {
free
(var-> font_abc_glyphs_ranges);
var-> font_abc_glyphs_ranges = NULL;
var-> font_abc_glyphs_n_ranges = 0;
}
}
Font *
Drawable_font_match(
char
* dummy, Font * source, Font * dest, Bool pick)
{
if
( pick)
apc_font_pick( NULL_HANDLE, source, dest);
else
Drawable_font_add( NULL_HANDLE, source, dest);
return
dest;
}
Bool
Drawable_font_add( Handle self, Font * source, Font * dest)
{
#define SRC(x) (!source->undef.x)
#define DST(x) (!dest->undef.x)
#define COPY(x) if (SRC(x)) { dest->x = source->x; dest->undef.x = 0; }
if
( dest != source) {
COPY(height);
COPY(width);
COPY(direction);
COPY(style);
COPY(pitch);
COPY(size);
COPY(vector);
if
(SRC(name)) {
strcpy
( dest-> name, source-> name);
dest->is_utf8.name = source->is_utf8.name;
dest->undef.name = 0;
}
if
( SRC(encoding)) {
strcpy
( dest-> encoding, source-> encoding);
dest->is_utf8.encoding = source->is_utf8.encoding;
dest->undef.encoding = 0;
}
}
if
( SRC(height))
dest->undef.size = 1;
else
if
(SRC(size))
dest->undef.height = 1;
if
( DST(size) && DST(height))
dest->undef.size = 1;
if
( !SRC(width) && (DST(pitch) || DST(height) || DST(name) || DST(size) || DST(direction) || DST(style)))
dest->undef.width = 1;
if
( !SRC(pitch) && (DST(name) || DST(size) || DST(direction) || DST(style)))
dest->undef.pitch = 1;
if
( dest-> pitch == fpDefault)
dest->undef.pitch = 1;
if
( dest-> vector == fvDefault)
dest->undef.vector = 1;
if
( dest-> width == 0)
dest->undef.width = 1;
if
( dest-> name[0] == 0 ||
strcmp
(dest->name,
"Default"
) == 0 ) {
dest->undef.name = 1;
}
if
( !DST(size))
dest->size = 0;
if
( !DST(height))
dest->height = 0;
if
( !DST(direction))
dest->direction = 0;
if
( !DST(style))
dest->style = 0;
if
( !DST(pitch))
dest->pitch = fpDefault;
if
( !DST(vector))
dest->vector = fvDefault;
if
( !DST(width))
dest->width = 0;
if
( !DST(name)) {
strcpy
( dest-> name,
"Default"
);
dest->is_utf8.name =
false
;
}
if
( !DST(encoding))
dest->encoding[0] = 0;
#define CLAMP(x) if ( DST(x) && dest->x <= 0) dest->x = 1; else if ( dest->x > 16383 ) dest->x = 16383
CLAMP(size);
CLAMP(height);
CLAMP(width);
#undef CLAMP
if
(DST(size))
dest-> size = FONT_SIZE_ROUND(dest->size);
return
dest->undef.height;
#undef SRC
#undef DST
#undef COPY
}
SV *
Drawable_get_font_abcdef( Handle self,
int
first,
int
last,
int
flags, PFontABC (*func)(Handle,
int
,
int
,
int
))
{
int
i;
AV * av;
PFontABC abc;
if
( first < 0) first = 0;
if
( last < 0) last = 255;
if
( flags & toGlyphs )
flags &= ~toUTF8;
else
if
( !(flags & toUTF8)) {
if
( first > 255) first = 255;
if
( last > 255) last = 255;
}
if
( first > last)
abc = NULL;
else
{
dmARGS;
dmENTER( newRV_noinc(( SV *) newAV()));
abc = func( self, first, last, flags );
dmLEAVE;
}
av = newAV();
if
( abc != NULL) {
for
( i = 0; i <= last - first; i++) {
av_push( av, newSVnv( abc[ i]. a));
av_push( av, newSVnv( abc[ i]. b));
av_push( av, newSVnv( abc[ i]. c));
}
free
( abc);
}
return
newRV_noinc(( SV *) av);
}
SV *
Drawable_get_font_abc( Handle self,
int
first,
int
last,
int
flags)
{
dmCHECK(NULL_SV);
return
Drawable_get_font_abcdef( self, first, last, flags, apc_gp_get_font_abc);
}
SV *
Drawable_get_font_def( Handle self,
int
first,
int
last,
int
flags)
{
dmCHECK(NULL_SV);
return
Drawable_get_font_abcdef( self, first, last, flags, apc_gp_get_font_def);
}
SV *
Drawable_get_font_languages( Handle self)
{
char
*buf, *p;
AV * av = newAV();
dmARGS;
dmCHECK(NULL_SV);
dmENTER( newRV_noinc(( SV *) av));
p = buf = apc_gp_get_font_languages( self);
dmLEAVE;
if
(p) {
while
(*p) {
int
len =
strlen
(p);
av_push(av, newSVpv(p, len));
p += len + 1;
}
free
(buf);
}
return
newRV_noinc(( SV *) av);
}
SV *
Drawable_get_font_ranges( Handle self)
{
int
count = 0;
unsigned
long
* ret;
AV * av = newAV();
dmARGS;
dmCHECK(NULL_SV);
dmENTER( newRV_noinc(( SV *) av));
ret = apc_gp_get_font_ranges( self, &count);
dmLEAVE;
if
( ret) {
int
i;
for
( i = 0; i < count; i++)
av_push( av, newSViv( ret[i]));
free
( ret);
}
return
newRV_noinc(( SV *) av);
}
Font
Drawable_get_font( Handle self)
{
return
var-> font;
}
void
Drawable_set_font( Handle self, Font font)
{
Drawable_clear_font_abc_caches( self);
apc_font_pick( self, &font, &var-> font);
apc_gp_set_font( self, &var-> font);
opt_clear(optFontTrigCache);
}
#ifdef __cplusplus
}
#endif