"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "layer1/FontType.cpp" between
pymol-v2.1.0.tar.bz2 and pymol-open-source-2.2.0.tar.gz

About: PyMOL is a Python-enhanced molecular graphics tool. It excels at 3D visualization of proteins, small molecules, density, surfaces, and trajectories. It also includes molecular editing, ray tracing, and movies. Open Source version.

FontType.cpp  (pymol-v2.1.0.tar.bz2):FontType.cpp  (pymol-open-source-2.2.0)
skipping to change at line 17 skipping to change at line 17
E* It is unlawful to modify or remove this copyright notice. E* It is unlawful to modify or remove this copyright notice.
F* ------------------------------------------------------------------- F* -------------------------------------------------------------------
G* Please see the accompanying LICENSE file for further information. G* Please see the accompanying LICENSE file for further information.
H* --------------------------------------------------\----------------- H* --------------------------------------------------\-----------------
I* Additional authors of this source file include: I* Additional authors of this source file include:
-* -*
-* -*
-* -*
Z* ------------------------------------------------------------------- Z* -------------------------------------------------------------------
*/ */
#include <algorithm>
#include"os_python.h" #include"os_python.h"
#include "MemoryDebug.h" #include "MemoryDebug.h"
#include "OOMac.h" #include "OOMac.h"
#include "os_gl.h" #include "os_gl.h"
#include "FontType.h" #include "FontType.h"
#include "Text.h" #include "Text.h"
#include "Ortho.h" #include "Ortho.h"
#include "Scene.h" #include "Scene.h"
#include "Character.h" #include "Character.h"
#include "Util.h" #include "Util.h"
#include "TypeFace.h" #include "TypeFace.h"
#define max2 std::max
static void CheckUnicode(unsigned int *c, int *unicnt, int *unicode){
if(*unicnt) {
if(!(*c & 0x80)) /* corrupt UTF8 */
*unicnt = 0;
else {
*unicode = ((*unicode) << 6) | (0x3F & *c);
(*unicnt)--;
*c = *unicode;
}
} else if(*c & 0x80) {
while(*c & 0x80) {
*c = (*c << 1) & 0xFF;
(*unicnt)++;
}
*unicode = (*c >> ((*unicnt)--));
}
}
static void GenerateCharFngrprnt(PyMOLGlobals *G, CharFngrprnt *fprnt, unsigned
int c, int TextID, float size, int sampling, short no_flat, int flat){
unsigned char *rgba;
UtilZeroMem(fprnt, sizeof(CharFngrprnt));
fprnt->u.i.text_id = TextID;
fprnt->u.i.size = (int) (size * 64 * sampling);
rgba = fprnt->u.i.color;
if (!TextGetIsPicking(G)){
TextGetColorUChar(G, rgba, rgba + 1, rgba + 2, rgba + 3);
rgba = fprnt->u.i.outline_color;
if (no_flat || !flat){
TextGetOutlineColor(G, rgba, rgba + 1, rgba + 2, rgba + 3);
} else if(flat) {
TextGetColorUChar(G, rgba, rgba + 1, rgba + 2, rgba + 3);
}
}
fprnt->u.i.ch = c;
fprnt->u.i.flat = flat;
}
typedef struct { typedef struct {
CFont Font; /* must be first */ CFont Font; /* must be first */
PyMOLGlobals *G; PyMOLGlobals *G;
CTypeFace *TypeFace; CTypeFace *TypeFace;
} CFontType; } CFontType;
#ifdef _PYMOL_INLINE #ifdef _PYMOL_INLINE
__inline__ __inline__
#endif #endif
static const char *_FontTypeRenderOpenGL(RenderInfo * info, static const char *_FontTypeRenderOpenGL(RenderInfo * info,
CFontType * I, const char *st, CFontType * I, const char *st,
float size, int flat, float *rpos SHADERCGOAR G) float size, int flat, float *rpos, short need Size, short relativeMode, short shouldRender SHADERCGOARG)
{ {
PyMOLGlobals *G = I->Font.G; PyMOLGlobals *G = I->Font.G;
if(G->ValidContext) { if(G->ValidContext) {
unsigned int c; unsigned int c;
int pushed = OrthoGetPushed(G); int pushed = OrthoGetPushed(G);
int kern_flag = false; int kern_flag = false;
unsigned int last_c = 0; unsigned int last_c = 0;
int sampling = 1; int sampling = 1;
const float _0 = 0.0F, _1 = 1.0F, _m1 = -1.0F; const float _0 = 0.0F, _1 = 1.0F, _m1 = -1.0F;
float x_indent = 0.0F, y_indent = 0.0F, z_indent = 0.0F; float x_indent = 0.0F, y_indent = 0.0F, z_indent = 0.0F;
float text_width = 0.f; float text_width = 0.f, line_width = 0.f, tot_text_width;
float text_just = 1.f - TextGetJustification(G);
float text_spacing = TextGetSpacing(G);
float text_buffer[2];
int unicode = 0; int unicode = 0;
int unicnt = 0; int unicnt = 0;
int nlines = countchrs(st, '\n') + 1;
int linenum = 0;
short cont = 0;
float descender = TypeFaceGetDescender(I->TypeFace) / 2.f;
float v_scale = SceneGetScreenVertexScale(G, NULL);
copy2f(TextGetLabelBuffer(G), text_buffer);
sampling = info->sampling; sampling = info->sampling;
if(st && (*st)) { if(st && (*st)) {
float v_scale; float *line_widths = NULL;
float screenWorldOffset[3] = { 0.0F, 0.0F, 0.0F }; float screenWorldOffset[3] = { 0.0F, 0.0F, 0.0F };
float tot_height;
v_scale = SceneGetScreenVertexScale(G, NULL); if (nlines>1){
line_widths = Calloc(float, nlines);
}
if(size < _0) { if(size < _0) {
size = (int) (0.5F - size / v_scale); size = (int) (0.5F - size / v_scale);
if (size <= 0) if (size <= 0)
size = 1; size = 1;
} else { } else {
size = DIP2PIXEL(size); size = DIP2PIXEL(size);
} }
text_buffer[0] *= size;
text_buffer[1] *= size;
if(rpos) { if(rpos) {
if(rpos[0] < _1) { /* we need to measure the string width before st TextSetIndentFactorX(G, rpos[0] < _m1 ? _m1 : rpos[0] > 1.f ? 1.f : rpos[
arting to draw */ 0]);
TextSetIndentFactorY(G, rpos[1] < _m1 ? _m1 : rpos[1] > 1.f ? 1.f : rpos[
1]);
if(needSize || rpos[0] < _1) { /* we need to measure the string wid
th before starting to draw */
const char *sst = st; const char *sst = st;
while((c = *(sst++))) { while((c = *(sst++))) {
if(unicnt) { if (c == '\n'){
if(!(c & 0x80)) /* corrupt UTF8 */ line_widths[linenum] = line_width;
unicnt = 0; text_width = max2(text_width, line_width);
else { line_width = 0.f;
unicode = (unicode << 6) | (0x3F & c); linenum++;
unicnt--; continue;
c = unicode; }
} CheckUnicode(&c, &unicnt, &unicode);
} else if(c & 0x80) {
while(c & 0x80) {
c = (c << 1) & 0xFF;
unicnt++;
}
unicode = (c >> (unicnt--));
}
if(!unicnt) { if(!unicnt) {
CharFngrprnt fprnt; CharFngrprnt fprnt;
unsigned char *rgba; GenerateCharFngrprnt(G, &fprnt, c, I->Font.TextID, size, sampling,
UtilZeroMem(&fprnt, sizeof(fprnt)); 0, flat);
fprnt.u.i.text_id = I->Font.TextID;
fprnt.u.i.size = (int) (size * 64 * sampling);
rgba = fprnt.u.i.color;
TextGetColorUChar(G, rgba, rgba + 1, rgba + 2, rgba + 3);
rgba = fprnt.u.i.outline_color;
if(!flat) {
TextGetOutlineColor(G, rgba, rgba + 1, rgba + 2, rgba + 3);
} else {
TextGetColorUChar(G, rgba, rgba + 1, rgba + 2, rgba + 3);
}
fprnt.u.i.ch = c;
fprnt.u.i.flat = flat;
{ {
int id = CharacterFind(G, &fprnt); int id = CharacterFind(G, &fprnt);
if(!id) { if(!id) {
id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling ); id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling );
} }
if(id) { if(id) {
if(kern_flag) { if(kern_flag) {
text_width += (TypeFaceGetKerning(I->TypeFace, line_width += (TypeFaceGetKerning(I->TypeFace,
last_c, c, size) / sampling); last_c, c, size) / sampling);
} }
text_width += CharacterGetAdvance(G, sampling, id); line_width += CharacterGetAdvance(G, sampling, id);
} }
} }
kern_flag = true; kern_flag = true;
last_c = c; last_c = c;
} }
} }
if (line_widths)
line_widths[linenum] = line_width;
text_width = max2(text_width, line_width) ;
tot_text_width = text_width + 2.f * text_buffer[0];
TextSetWidth(G, tot_text_width);
tot_height = pymol_roundf(size * (nlines + (nlines-1) * (text_spacing-1
.f)) + 2.f * text_buffer[1]);
TextSetHeight(G, tot_height);
{ {
float factor = rpos[0] / 2.0F - 0.5F; float factor = rpos[0] / 2.0F - 0.5F;
/* if -1. < rpos[0] < 1. , then we need to determine the label's widt h /* if -1. < rpos[0] < 1. , then we need to determine the label's widt h
so that we can justify it appropriately */ so that we can justify it appropriately */
if(factor < _m1) // if rpos[0] < -1., right justified // if rpos[0] < -1., right justified
factor = -_1; // if rpos[0] > 1., left justified, label width not needed
if(factor > _0) // if rpos[0] > 1., left justified, label width not factor = (factor < _m1) ? _m1 : (factor > _0) ? _0 : factor;
needed x_indent -= factor * tot_text_width;
factor = _0;
x_indent -= factor * text_width;
} }
} }
/* if label_position x is -1 to 1, the label is placed in x such that /* if label_position x is -1 to 1, the label is placed in x such that
0 - centered 0 - centered
-1 - right justified on projected point -1 - right justified on projected point
1 - left justified on projected point 1 - left justified on projected point
*/ */
if(rpos[0] < _m1) { if(rpos[0] < _m1) {
screenWorldOffset[0] -= (rpos[0] + _1);// / v_scale; screenWorldOffset[0] -= (rpos[0] + _1);
} else if(rpos[0] > _1) { } else if(rpos[0] > _1) {
screenWorldOffset[0] -= (rpos[0] - _1);// / v_scale; screenWorldOffset[0] -= (rpos[0] - _1);
} }
if(rpos[1] < _1) { if(rpos[1] < _1) {
float factor = -rpos[1] / 2.0F + 0.5F; float factor = -rpos[1] / 2.0F + 0.5F;
if(factor > _1) factor = (factor > _1) ? _1 : (factor < _0) ? _0 : factor;
factor = _1; y_indent = pymol_roundf((size * factor) * (1.f + text_spacing * max2(0.
if(factor < _0) f, nlines-1.f)));
factor = _0; }
y_indent = 0.75 * size * factor; {
float factor = rpos[1];
factor = (factor > _1) ? _1 : (factor < _m1) ? _m1 : factor;
y_indent -= pymol_roundf(factor * text_buffer[1]);
} }
if(rpos[1] < _m1) { if(rpos[1] < _m1) {
screenWorldOffset[1] -= (rpos[1] + _1); screenWorldOffset[1] -= (rpos[1] + _1);
} else if(rpos[1] > _1) { } else if(rpos[1] > _1) {
screenWorldOffset[1] -= (rpos[1] - _1); screenWorldOffset[1] -= (rpos[1] - _1);
} }
/* leave room for fonts of finite depth */ /* leave room for fonts of finite depth */
z_indent = (rpos[2] < _m1) ? (rpos[2]+1.f) : (rpos[2] > 1.f) ? (rpos[2]-1 .f) : 0.f; z_indent = (rpos[2] < _m1) ? (rpos[2]+1.f) : (rpos[2] > 1.f) ? (rpos[2]-1 .f) : 0.f;
if (!shaderCGO){ if (!shaderCGO){
x_indent += screenWorldOffset[0] / v_scale; x_indent += screenWorldOffset[0] / v_scale;
y_indent += screenWorldOffset[1] / v_scale; y_indent += pymol_roundf(screenWorldOffset[1] / v_scale);
} }
screenWorldOffset[2] += z_indent; // need to take into account weird -1 t o 1, and sub 1 from abs val screenWorldOffset[2] += z_indent; // need to take into account weird -1 t o 1, and sub 1 from abs val
} }
if(!pushed) { if(!pushed) {
float *v = TextGetPos(G); float *v = TextGetPos(G);
float loc[3]; float loc[3];
float zero[3] = { 0.0F, 0.0F, 0.0F }; float zero[3] = { 0.0F, 0.0F, 0.0F };
TextSetScreenWorldOffset(G, screenWorldOffset); TextSetScreenWorldOffset(G, screenWorldOffset);
TextSetWorldPos(G, v); TextSetWorldPos(G, v);
if(rpos) { if(rpos) {
if(info->ortho) { if(info->ortho) {
float orig[3]; float orig[3];
SceneOriginGet(G, orig); SceneOriginGet(G, orig);
SceneGetEyeNormal(G, orig, loc); SceneGetEyeNormal(G, orig, loc);
} else { } else {
SceneGetEyeNormal(G, v, loc); SceneGetEyeNormal(G, v, loc);
} }
scale3f(loc, z_indent, loc); scale3f(loc, z_indent, loc);
add3f(v, loc, loc); add3f(v, loc, loc);
v = loc; v = loc;
} }
if (!shaderCGO){
unsigned char posIsSet = TextGetLabelPosIsSet(G);
switch (posIsSet){
case 1:
SceneAdjustZtoScreenZ(G, v, TextGetLabelPos(G)[0]);
break;
case 2:
SceneSetPointToWorldScreenRelative(G, v, TextGetLabelPos(G));
break;
}
}
TextSetLabelPushPos(G, v);
if (!shouldRender)
return st;
ScenePushRasterMatrix(G, v); ScenePushRasterMatrix(G, v);
TextSetPos(G, zero); TextSetPos(G, zero);
#ifndef PURE_OPENGL_ES_2
} else {
#endif
if (!shouldRender)
return st;
} }
if(rpos) { if(rpos) {
// float ax = x_indent * v_scale, ay = y_indent * v_scale;
// printf("x_indent=%f y_indent=%f ax=%f ay=%f v_scale=%f rpos=%f %f
%f\n", x_indent, y_indent, ax, ay, v_scale, rpos[0], rpos[1], rpos[2]);
TextIndent(G, x_indent, y_indent); TextIndent(G, x_indent, y_indent);
} }
CharacterRenderOpenGLPrime(G, info); CharacterRenderOpenGLPrime(G, info);
while((c = *(st++))) { kern_flag = false;
if(unicnt) { TextGetPos(G)[1] += (int)pymol_roundf(size * (text_spacing * (nlines-1) +
if(!(c & 0x80)) /* corrupt UTF8 */ descender));
unicnt = 0; if (line_widths){
else { TextGetPos(G)[0] += text_just * (text_width - line_widths[0])/2.f;
unicode = (unicode << 6) | (0x3F & c); }
unicnt--; TextGetPos(G)[0] += text_buffer[0];
c = unicode; linenum = 0;
} cont = 1;
} else if(c & 0x80) { while(cont && (c = *(st++))) {
while(c & 0x80) { if (c == '\n'){
c = (c << 1) & 0xFF; float zero[3] = { 0.0F, 0.0F, 0.0F };
unicnt++; TextSetPos(G, zero);
} if (rpos){
unicode = (c >> (unicnt--)); TextIndent(G, x_indent, y_indent);
} }
linenum++;
TextGetPos(G)[1] += (int)pymol_roundf(size * (text_spacing * (nlines -
1 - linenum) + descender));
if (line_widths)
TextGetPos(G)[0] += text_just * (text_width - line_widths[linenum])/2
.f + text_buffer[0];
kern_flag = false;
continue;
}
CheckUnicode(&c, &unicnt, &unicode);
if(!unicnt) { if(!unicnt) {
CharFngrprnt fprnt; CharFngrprnt fprnt;
unsigned char *rgba; GenerateCharFngrprnt(G, &fprnt, c, I->Font.TextID, size, sampling, 1, f
UtilZeroMem(&fprnt, sizeof(fprnt)); lat);
fprnt.u.i.text_id = I->Font.TextID;
fprnt.u.i.size = (int) (size * 64 * sampling);
rgba = fprnt.u.i.color;
TextGetColorUChar(G, rgba, rgba + 1, rgba + 2, rgba + 3);
rgba = fprnt.u.i.outline_color;
TextGetOutlineColor(G, rgba, rgba + 1, rgba + 2, rgba + 3);
fprnt.u.i.ch = c;
fprnt.u.i.flat = flat;
{ {
int id = CharacterFind(G, &fprnt); int id = CharacterFind(G, &fprnt);
if(!id) { if(!id) {
id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling); id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling);
} }
if(id) { if(id) {
if(kern_flag) { if(kern_flag) {
TextAdvance(G, TypeFaceGetKerning(I->TypeFace, TextAdvance(G, TypeFaceGetKerning(I->TypeFace,
last_c, c, size) / sampling); last_c, c, size) / sampling);
} }
CharacterRenderOpenGL(G, info, id, true SHADERCGOARGVAR); /* handles advance */ cont &= CharacterRenderOpenGL(G, info, id, true, relativeMode SHAD ERCGOARGVAR); /* handles advance */
} }
} }
kern_flag = true; kern_flag = true;
last_c = c; last_c = c;
} }
} }
CharacterRenderOpenGLDone(G, info); CharacterRenderOpenGLDone(G, info);
if(!pushed) { if(!pushed) {
ScenePopRasterMatrix(G); ScenePopRasterMatrix(G);
} }
FreeP(line_widths);
} }
if (!cont)
return st;
} }
return st; return st;
} }
static const char *FontTypeRenderOpenGL(RenderInfo * info, CFontType * I, const char *st, float size, static const char *FontTypeRenderOpenGL(RenderInfo * info, CFontType * I, const char *st, float size,
float *rpos SHADERCGOARG) float *rpos, short needSize, short relativeMod e, short shouldRender SHADERCGOARG)
{ {
return _FontTypeRenderOpenGL(info, I, st, size, false, rpos SHADERCGOARGVAR); return _FontTypeRenderOpenGL(info, I, st, size, false, rpos, needSize, relativ eMode, shouldRender SHADERCGOARGVAR);
} }
static const char *FontTypeRenderOpenGLFlat(RenderInfo * info, CFontType * I, co nst char *st, static const char *FontTypeRenderOpenGLFlat(RenderInfo * info, CFontType * I, co nst char *st,
float size, float *rpos SHADERCGOARG) float size, float *rpos, short needSize, s hort relativeMode, short shouldRender SHADERCGOARG)
{ {
return _FontTypeRenderOpenGL(info, I, st, size, true, rpos SHADERCGOARGVAR); return _FontTypeRenderOpenGL(info, I, st, size, true, rpos, needSize, relative Mode, shouldRender SHADERCGOARGVAR);
} }
static const char *FontTypeRenderRay(CRay * ray, CFontType * I, const char *st, float size, static const char *FontTypeRenderRay(CRay * ray, CFontType * I, const char *st, float size,
float *rpos) float *rpos, short needSize, short relativeMode)
{ {
PyMOLGlobals *G = I->Font.G; PyMOLGlobals *G = I->Font.G;
unsigned int c; unsigned int c;
int kern_flag = false; int kern_flag = false;
unsigned int last_c = 0; unsigned int last_c = 0;
int sampling = ray->Sampling; int sampling = ray->Sampling;
const float _0 = 0.0F, _1 = 1.0F, _m1 = -1.0F; const float _0 = 0.0F, _1 = 1.0F, _m1 = -1.0F;
float x_indent = 0.0F, y_indent = 0.0F, z_indent = 0.0F; float x_indent = 0.0F, y_indent = 0.0F, z_indent = 0.0F;
float text_width = 0.f, line_width = 0.f, tot_text_width;
float text_just = 1.f - TextGetJustification(G);
float text_spacing = TextGetSpacing(G);
float text_buffer[2];
float xn[3], yn[3], x_adj[3], y_adj[3], pos[3], *v; float xn[3], yn[3], x_adj[3], y_adj[3], pos[3], *v;
int unicode = 0; int unicode = 0;
int unicnt = 0; int unicnt = 0;
int nlines = countchrs(st, '\n') + 1;
int linenum = 0;
float descender = TypeFaceGetDescender(I->TypeFace);
float v_scale = SceneGetScreenVertexScale(G, NULL);
copy2f(TextGetLabelBuffer(G), text_buffer);
if(st && (*st)) { if(st && (*st)) {
float v_scale = SceneGetScreenVertexScale(G, NULL); float origpos[3];
float *line_widths = NULL;
float tot_height;
if (nlines>1){
line_widths = Calloc(float, nlines);
}
if(size < _0) {
size = (int) (0.5F - size / v_scale);
} else {
size = DIP2PIXEL(size);
}
text_buffer[0] *= size;
text_buffer[1] *= size;
if(rpos) { if(rpos) {
float loc[3]; float loc[3];
/* leave room for fonts of finite depth */ /* leave room for fonts of finite depth */
z_indent = (rpos[2] < _m1) ? (rpos[2]+1.f) : (rpos[2] > 1.f) ? (rpos[2]-1. f) : 0.f; z_indent = (rpos[2] < _m1) ? (rpos[2]+1.f) : (rpos[2] > 1.f) ? (rpos[2]-1. f) : 0.f;
v = TextGetPos(I->G); v = TextGetPos(I->G);
if(ray->Ortho) { if(ray->Ortho) {
float orig[3]; float orig[3];
SceneOriginGet(G, orig); SceneOriginGet(G, orig);
SceneGetEyeNormal(G, orig, loc); SceneGetEyeNormal(G, orig, loc);
} else { } else {
SceneGetEyeNormal(G, v, loc); SceneGetEyeNormal(G, v, loc);
} }
scale3f(loc, z_indent, loc); scale3f(loc, z_indent, loc);
add3f(v, loc, loc); add3f(v, loc, loc);
{
unsigned char posIsSet = TextGetLabelPosIsSet(G);
switch (posIsSet){
case 1:
RayAdjustZtoScreenZ(ray, loc, TextGetLabelPos(G)[0]);
break;
case 2:
RaySetPointToWorldScreenRelative(ray, loc, TextGetLabelPos(G));
break;
}
}
TextSetLabelPushPos(G, loc);
TextSetPos(I->G, loc); TextSetPos(I->G, loc);
} }
RayGetScaledAxes(ray, xn, yn); RayGetScaledAxes(ray, xn, yn);
if(size < _0) {
size = (int) (0.5F - size / v_scale);
} else {
size = DIP2PIXEL(size);
}
if(rpos) { if(rpos) {
if(needSize || rpos[0] < _1) { /* we need to measure the string wid
if(rpos[0] < _1) { /* we need to measure the string width before st th before starting to draw */
arting to draw */
float factor = rpos[0] / 2.0F - 0.5F; float factor = rpos[0] / 2.0F - 0.5F;
const char *sst = st; const char *sst = st;
float max_x_indent = 0.f;
// factor -1 to 0 based on justification (i.e., rpos[0])
factor = (factor < _m1) ? _m1 : (factor > _0) ? _0 : factor; factor = (factor < _m1) ? _m1 : (factor > _0) ? _0 : factor;
while((c = *(sst++))) { while((c = *(sst++))) {
if(unicnt) { if (c == '\n'){
if(!(c & 0x80)) /* corrupt UTF8 */ text_width = max2(text_width, line_width);
unicnt = 0; line_widths[linenum] = line_width;
else { line_width = 0.f;
unicode = (unicode << 6) | (0x3F & c); kern_flag = false;
unicnt--; linenum++;
c = unicode; max_x_indent = max2(x_indent, max_x_indent);
} x_indent = 0.f;
} else if(c & 0x80) { continue;
while(c & 0x80) { }
c = (c << 1) & 0xFF; CheckUnicode(&c, &unicnt, &unicode);
unicnt++;
}
unicode = (c >> (unicnt--));
}
if(!unicnt) { if(!unicnt) {
CharFngrprnt fprnt; CharFngrprnt fprnt;
unsigned char *rgba; GenerateCharFngrprnt(G, &fprnt, c, I->Font.TextID, size, sampling, 1,
UtilZeroMem(&fprnt, sizeof(fprnt)); 0 /* flat is not set */);
fprnt.u.i.text_id = I->Font.TextID;
fprnt.u.i.size = (int) (size * 64 * sampling);
rgba = fprnt.u.i.color;
TextGetColorUChar(G, rgba, rgba + 1, rgba + 2, rgba + 3);
rgba = fprnt.u.i.outline_color;
TextGetOutlineColor(G, rgba, rgba + 1, rgba + 2, rgba + 3);
fprnt.u.i.ch = c;
{ {
int id = CharacterFind(G, &fprnt); int id = CharacterFind(G, &fprnt);
if(!id) { if(!id) {
id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling); id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling);
} }
if(id) { if(id) {
float adv;
if(kern_flag) { if(kern_flag) {
x_indent -= factor * TypeFaceGetKerning(I->TypeFace, float kern = TypeFaceGetKerning(I->TypeFace,
last_c, last_c,
c, size * sampling) / c, size * sampling) ;
sampling; line_width += kern;
x_indent -= factor * kern;
} }
x_indent -= factor * CharacterGetAdvance(G, 1, id); adv = CharacterGetAdvance(G, 1, id);
line_width += adv;
x_indent -= factor * adv;
kern_flag = true; kern_flag = true;
last_c = c; last_c = c;
} }
} }
} }
} }
max_x_indent = max2(x_indent, max_x_indent);
x_indent = max_x_indent;
} }
text_width = max2(text_width, line_width);
tot_text_width = text_width + 2.f * text_buffer[0] * sampling;
if (line_widths)
line_widths[linenum] = line_width;
TextSetWidth(G, tot_text_width/(float)sampling);
tot_height = size * (nlines + (nlines-1) * (text_spacing-1.f)) + 2.f * tex
t_buffer[1];
TextSetHeight(G, tot_height);
if(rpos[0] < _m1) { if(rpos[0] < _m1) {
x_indent -= 2 * (rpos[0] + _1) / v_scale; x_indent -= 2 * (rpos[0] + _1) / v_scale;
} else if(rpos[0] > _1) { } else if(rpos[0] > _1) {
x_indent -= 2 * (rpos[0] - _1) / v_scale; x_indent -= 2 * (rpos[0] - _1) / v_scale;
} }
if(rpos[1] < _1) { if(rpos[1] < _1) {
float factor = -rpos[1] / 2.0F + 0.5F; float factor = -rpos[1] / 2.0F + 0.5F;
if(factor > _1) factor = (factor > _1) ? _1 : (factor < _0) ? _0 : factor;
factor = _1; y_indent = (sampling * size * factor) * (1.f + text_spacing * max2(0.f, n
if(factor < _0) lines-1.f));
factor = _0; }
y_indent = 0.75F * sampling * size * factor; {
float factor = rpos[1];
factor = (factor > _1) ? _1 : (factor < _m1) ? _m1 : factor;
y_indent -= factor * sampling * text_buffer[1];
} }
if(rpos[1] < _m1) { if(rpos[1] < _m1) {
y_indent -= 2 * (rpos[1] + _1) / v_scale; y_indent -= 2 * (rpos[1] + _1) / v_scale;
} else if(rpos[1] > _1) { } else if(rpos[1] > _1) {
y_indent -= 2 * (rpos[1] - _1) / v_scale; y_indent -= 2 * (rpos[1] - _1) / v_scale;
} }
v = TextGetPos(I->G); v = TextGetPos(I->G);
if (line_widths){
x_indent -= text_just * (text_width - line_widths[0])/2.f;
}
{
float factor = rpos[0];
factor = (factor > _1) ? _1 : (factor < _m1) ? _m1 : factor;
x_indent -= factor * sampling * text_buffer[0];
}
scale3f(xn, x_indent, x_adj); scale3f(xn, x_indent, x_adj);
scale3f(yn, y_indent, y_adj); scale3f(yn, y_indent - size * (sampling * text_spacing * (nlines-1) + desc ender), y_adj);
subtract3f(v, x_adj, pos); subtract3f(v, x_adj, pos);
subtract3f(pos, y_adj, pos); subtract3f(pos, y_adj, pos);
TextSetPos(I->G, pos); TextSetPos(I->G, pos);
} }
kern_flag = false; kern_flag = false;
copy3f(TextGetPos(I->G), origpos);
linenum = 0;
while((c = *(st++))) { while((c = *(st++))) {
if(unicnt) { if (c == '\n'){
if(!(c & 0x80)) /* corrupt UTF8 */ copy3f(origpos, TextGetPos(I->G));
unicnt = 0; kern_flag = false;
else { linenum++;
unicode = (unicode << 6) | (0x3F & c); scale3f(yn, pymol_roundf(text_spacing * size * linenum * sampling), y_adj
unicnt--; ); // need to round to pixel in y
c = unicode; subtract3f(TextGetPos(G), y_adj, TextGetPos(G));
} if (line_widths){
} else if(c & 0x80) { scale3f(xn, text_just * (line_widths[0] - line_widths[linenum])/2.f, x_
while(c & 0x80) { adj);
c = (c << 1) & 0xFF; add3f(TextGetPos(G), x_adj, TextGetPos(G));
unicnt++; }
} kern_flag = false;
unicode = (c >> (unicnt--)); continue;
} }
CheckUnicode(&c, &unicnt, &unicode);
if(!unicnt) { if(!unicnt) {
CharFngrprnt fprnt; CharFngrprnt fprnt;
unsigned char *rgba; GenerateCharFngrprnt(G, &fprnt, c, I->Font.TextID, size, sampling, 0, 0);
UtilZeroMem(&fprnt, sizeof(fprnt));
fprnt.u.i.text_id = I->Font.TextID;
fprnt.u.i.size = (int) (size * 64 * sampling);
rgba = fprnt.u.i.color;
TextGetColorUChar(G, rgba, rgba + 1, rgba + 2, rgba + 3);
rgba = fprnt.u.i.outline_color;
TextGetOutlineColor(G, rgba, rgba + 1, rgba + 2, rgba + 3);
fprnt.u.i.ch = c;
{ {
int id = CharacterFind(G, &fprnt); int id = CharacterFind(G, &fprnt);
if(!id) { if(!id) {
id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling); id = TypeFaceCharacterNew(I->TypeFace, &fprnt, size * sampling);
} }
if(id) { if(id) {
if(kern_flag) { if(kern_flag) {
float kern = TypeFaceGetKerning(I->TypeFace, float kern = TypeFaceGetKerning(I->TypeFace,
last_c, last_c,
c, c,
size * sampling) / sampling; size * sampling);
v = TextGetPos(I->G); v = TextGetPos(I->G);
scale3f(xn, kern, x_adj); scale3f(xn, kern, x_adj);
add3f(v, x_adj, pos); add3f(v, x_adj, pos);
TextSetPos(I->G, pos); TextSetPos(I->G, pos);
} }
ray->character(id); /* handles advance */ ray->character(id); /* handles advance */
kern_flag = true; kern_flag = true;
last_c = c; last_c = c;
} }
} }
} }
} }
FreeP(line_widths);
} }
return st; return st;
} }
static void FontTypeFree(CFont * font) static void FontTypeFree(CFont * font)
{ {
CFontType *I = (CFontType *) font; CFontType *I = (CFontType *) font;
TypeFaceFree(I->TypeFace); TypeFaceFree(I->TypeFace);
OOFreeP(I); OOFreeP(I);
} }
 End of changes. 58 change blocks. 
162 lines changed or deleted 271 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)