Prima
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
class/Drawable/shape.c view on Meta::CPAN
#include "apricot.h"
#include "guts.h"
#include "Drawable.h"
#include "Application.h"
#include "Drawable_private.h"
#ifdef WITH_FRIBIDI
#include <fribidi/fribidi.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
static void*
warn_malloc(ssize_t size)
{
void * ret;
if (!(ret = malloc(size))) {
warn("Drawable.text_shape: not enough memory");
return NULL;
}
return ret;
}
static uint32_t*
sv2uint32( SV * text, unsigned int * size, unsigned int * flags)
{
STRLEN dlen;
register char * src;
uint32_t *ret;
src = SvPV(text, dlen);
if (prima_is_utf8_sv(text)) {
*flags |= toUTF8;
*size = prima_utf8_length(src, dlen);
} else {
*size = dlen;
}
if (!(ret = ( uint32_t*) warn_malloc(sizeof(uint32_t) * (*size))))
return NULL;
if (*flags & toUTF8 ) {
uint32_t *dst = ret;
while ( dlen > 0 && dst - ret < *size) {
STRLEN charlen;
UV uv;
uv = prima_utf8_uvchr(src, dlen, &charlen);
if ( uv > 0x10FFFF ) uv = 0x10FFFF;
*(dst++) = uv;
if ( charlen == 0 ) break;
src += charlen;
dlen -= charlen;
}
*size = dst - ret;
} else {
register int i = *size;
register uint32_t *dst = ret;
while (i-- > 0) *(dst++) = *((unsigned char*) src++);
}
return ret;
}
/*
Iterator for individual shaper runs. Each run has same direction
and its indexes are increasing/decreasing monotonically. The latter is
to avoid situations where text A<PDF>B is being sent to shaper as single run AB
which might ligate.
*/
typedef struct {
unsigned int i, vis_len;
} BidiRunRec, *PBidiRunRec;
static void
run_init(PBidiRunRec r, int visual_length)
{
r->i = 0;
r->vis_len = visual_length;
}
static int
run_next(PTextShapeRec t, PBidiRunRec r)
{
int rtl, font, start = r->i;
if ( r->i >= r->vis_len ) return 0;
rtl = t->analysis[r->i];
font = t->fonts ? t->fonts[r->i] : 0;
for ( ; r->i < r->vis_len + 1; r->i++) {
if (
r->i >= r->vis_len || /* eol */
(t-> analysis[r->i] != rtl) || /* rtl != ltr */
(t->fonts && font != t->fonts[r->i])
) {
return r->i - start;
}
}
return 0;
}
#define INVERT(_type,_start,_end) \
{ \
register _type *s = _start, *e = _end;\
while ( s < e ) { \
view all matches for this distributionview release on metacpan - search on metacpan
( run in 0.351 second using v1.00-cache-2.02-grep-82fe00e-cpan-503542c4f10 )