TT_Error Context_Create( void* _context, void* _face ) { /* Note : The function name is a kind of misleading due to our improvement. * Now it adjusts (enhances) the context for the specified face. * We keep the old Free Type's name for easier localization of our changes. * The context must be initialized with zeros before the first call. * (igorm). */ PExecution_Context exec = (PExecution_Context)_context; PFace face = (PFace)_face; ttfMemory *mem = face->font->tti->ttf_memory; TMaxProfile *maxp = &face->maxProfile; Int n_points, n_twilight; Int callSize, stackSize; callSize = 32; exec->memory = mem; /* reserve a little extra for broken fonts like courbs or timesbs */ stackSize = maxp->maxStackElements + 32; n_points = face->maxPoints + 2; n_twilight = maxp->maxTwilightPoints; if (n_points < 100) n_points = 100; /* Bug 689907 */ if ( ALLOC_ARRAY( exec->callStack, exec->callSize, callSize, TCallRecord ) || /* reserve interpreter call stack */ ALLOC_ARRAY( exec->stack, exec->stackSize, stackSize, Long ) || /* reserve interpreter stack */ ALLOC_ARRAY( exec->pts.org_x, exec->n_points, n_points, TT_F26Dot6 ) || ALLOC_ARRAY( exec->pts.org_y, exec->n_points, n_points, TT_F26Dot6 ) || ALLOC_ARRAY( exec->pts.cur_x, exec->n_points, n_points, TT_F26Dot6 ) || ALLOC_ARRAY( exec->pts.cur_y, exec->n_points, n_points, TT_F26Dot6 ) || ALLOC_ARRAY( exec->pts.touch, exec->n_points, n_points, Byte ) || /* reserve points zone */ ALLOC_ARRAY( exec->twilight.org_x, exec->twilight.n_points, n_twilight, TT_F26Dot6 ) || ALLOC_ARRAY( exec->twilight.org_y, exec->twilight.n_points, n_twilight, TT_F26Dot6 ) || ALLOC_ARRAY( exec->twilight.cur_x, exec->twilight.n_points, n_twilight, TT_F26Dot6 ) || ALLOC_ARRAY( exec->twilight.cur_y, exec->twilight.n_points, n_twilight, TT_F26Dot6 ) || ALLOC_ARRAY( exec->twilight.touch, exec->twilight.n_points, n_twilight, Byte ) || /* reserve twilight zone */ ALLOC_ARRAY( exec->pts.contours, exec->n_contours, face->maxContours, UShort ) /* reserve contours array */ ) goto Fail_Memory; SETMAX(exec->callSize, callSize); SETMAX(exec->stackSize, stackSize); SETMAX(exec->twilight.n_points, n_twilight); SETMAX(exec->maxGlyphSize, maxp->maxSizeOfInstructions); SETMAX(exec->n_contours, face->maxContours); SETMAX(exec->n_points, n_points); exec->lock++; return TT_Err_Ok; Fail_Memory: /* Context_Destroy( exec ); Don't release buffers because the context is shared. */ return TT_Err_Out_Of_Memory; }
/* ** Break markup is any kind of markup that might force a line-break. This ** routine handles a single element of break markup and returns a pointer ** to the first element past that markup. If p doesn't point to break ** markup, then p is returned. If p is an incomplete table (a <TABLE> ** that lacks a </TABLE>), then NULL is returned. */ static HtmlElement *DoBreakMarkup( HtmlLayoutContext *pLC, HtmlElement *p ){ HtmlElement *pNext = p->pNext; char *z; int x, y, w; switch( p->base.type ){ case Html_A: p->anchor.y = pLC->bottom; TestPoint(0); break; case Html_BLOCKQUOTE: HtmlPushMargin(&pLC->leftMargin, HTML_INDENT, -1, Html_EndBLOCKQUOTE); HtmlPushMargin(&pLC->rightMargin, HTML_INDENT, -1, Html_EndBLOCKQUOTE); Paragraph(pLC, p); TestPoint(0); break; case Html_EndBLOCKQUOTE: HtmlPopMargin(&pLC->leftMargin, Html_EndBLOCKQUOTE, pLC); HtmlPopMargin(&pLC->rightMargin, Html_EndBLOCKQUOTE, pLC); Paragraph(pLC, p); TestPoint(0); break; case Html_IMG: switch( p->image.align ){ case IMAGE_ALIGN_Left: HtmlComputeMargins(pLC, &x, &y, &w); p->image.x = x; p->image.y = y; p->image.ascent = 0; p->image.descent = p->image.h; HtmlPushMargin(&pLC->leftMargin, p->image.w + 2, y + p->image.h, 0); SETMAX( pLC->maxY, y + p->image.h ); SETMAX( pLC->maxX, x + p->image.w ); break; case IMAGE_ALIGN_Right: HtmlComputeMargins(pLC, &x, &y, &w); p->image.x = x + w - p->image.w; p->image.y = y; p->image.ascent = 0; p->image.descent = p->image.h; HtmlPushMargin(&pLC->rightMargin, p->image.w + 2, y + p->image.h, 0); SETMAX( pLC->maxY, y + p->image.h ); SETMAX( pLC->maxX, x + p->image.w ); break; default: TestPoint(0); pNext = p; break; } break; case Html_PRE: /* Skip space tokens thru the next newline. */ while( pNext->base.type==Html_Space ){ HtmlElement *pThis = pNext; pNext = pNext->pNext; if( pThis->base.flags & HTML_NewLine ){ TestPoint(0); break; } } Paragraph(pLC,p); break; case Html_UL: case Html_MENU: case Html_DIR: case Html_OL: if( p->list.compact==0 ){ Paragraph(pLC,p); } HtmlPushMargin(&pLC->leftMargin, HTML_INDENT, -1, p->base.type+1); break; case Html_EndOL: case Html_EndUL: case Html_EndMENU: case Html_EndDIR: if( p->ref.pOther ){ HtmlPopMargin(&pLC->leftMargin, p->base.type, pLC); if( !p->ref.pOther->list.compact ){ Paragraph(pLC,p); } } break; case Html_DL: Paragraph(pLC,p); HtmlPushMargin(&pLC->leftMargin, HTML_INDENT, -1, Html_EndDL); TestPoint(0); break; case Html_EndDL: HtmlPopMargin(&pLC->leftMargin, Html_EndDL, pLC); Paragraph(pLC,p); TestPoint(0); break; case Html_HR: { int zl, wd; p->hr.is3D = HtmlMarkupArg(p, "noshade", 0)==0; z = HtmlMarkupArg(p, "size", 0); if( z ){ p->hr.h = atoi(z); }else{ p->hr.h = 0; } if( p->hr.h<1 ){ int relief = pLC->htmlPtr->ruleRelief; if( p->hr.is3D && (relief==TK_RELIEF_SUNKEN || relief==TK_RELIEF_RAISED) ){ p->hr.h = 3; }else{ p->hr.h = 2; } } HtmlComputeMargins(pLC, &x, &y, &w); p->hr.y = y; y += p->hr.h + 1; p->hr.x = x; z = HtmlMarkupArg(p, "width", "100%"); zl = strlen(z); if( zl>0 && z[zl-1]=='%' ){ wd = (atoi(z)*w)/100; }else{ wd = atoi(z); } if( wd>w ) wd = w; p->hr.w = wd; switch( p->base.style.align ){ case ALIGN_Center: case ALIGN_None: p->hr.x += (w - wd)/2; TestPoint(0); break; case ALIGN_Right: p->hr.x += (w - wd); TestPoint(0); break; default: TestPoint(0); break; } SETMAX( pLC->maxY, y); SETMAX( pLC->maxX, wd + p->hr.x ); pLC->bottom = y; pLC->headRoom = 0; break; } case Html_ADDRESS: case Html_EndADDRESS: case Html_CENTER: case Html_EndCENTER: case Html_DIV: case Html_EndDIV: case Html_H1: case Html_EndH1: case Html_H2: case Html_EndH2: case Html_H3: case Html_EndH3: case Html_H4: case Html_EndH4: case Html_H5: case Html_EndH5: case Html_H6: case Html_EndH6: case Html_P: case Html_EndP: case Html_EndPRE: Paragraph(pLC, p); TestPoint(0); break; case Html_TABLE: pNext = HtmlTableLayout(pLC, p); TestPoint(0); break; case Html_BR: z = HtmlMarkupArg(p, "clear",0); if( z ){ if( stricmp(z,"left")==0 ){ ClearObstacle(pLC, CLEAR_Left); TestPoint(0); }else if( stricmp(z,"right")==0 ){ ClearObstacle(pLC, CLEAR_Right); TestPoint(0); }else{ ClearObstacle(pLC, CLEAR_Both); TestPoint(0); } }else{ TestPoint(0); } break; /* All of the following tags need to be handed to the GetLine() routine */ case Html_Text: case Html_Space: case Html_LI: case Html_INPUT: case Html_SELECT: case Html_TEXTAREA: case Html_APPLET: case Html_EMBED: pNext = p; TestPoint(0); break; default: TestPoint(0); break; } return pNext; }
STATIC MYBOOL updatePricer(lprec *lp, int rownr, int colnr, REAL *pcol, REAL *prow, int *nzprow) { REAL *vEdge = NULL, cEdge, hold, *newEdge, *w = NULL; int i, m, n, exitcol, errlevel = DETAILED; MYBOOL forceRefresh = FALSE, isDual, isDEVEX, ok = FALSE; if(!applyPricer(lp)) return(ok); /* Make sure we have something to update */ hold = lp->edgeVector[0]; if(hold < 0) return(ok); isDual = (MYBOOL) (hold > 0); /* Do common initializations and computations */ m = lp->rows; n = lp->sum; isDEVEX = is_piv_rule(lp, PRICER_DEVEX); exitcol = lp->var_basic[rownr]; /* Solve/copy Bw = a */ #if 0 ok = formWeights(lp, colnr, NULL, &w); /* Compute from scratch - Experimental */ #else ok = formWeights(lp, colnr, pcol, &w); /* Use previously computed values */ #endif if(!ok) return( ok ); /* Price norms for the dual simplex - the basic columns */ if(isDual) { REAL rw; int targetcol; /* Don't need to compute cross-products with DEVEX */ if(!isDEVEX) { ok = allocREAL(lp, &vEdge, m+1, FALSE); if(!ok) return( ok ); /* Extract the row of the inverse containing the leaving variable and then form the dot products against the other variables, i.e. "Tau" */ #if 0 /* Extract row explicitly */ bsolve(lp, rownr, vEdge, 0, 0.0); #else /* Reuse previously extracted row data */ MEMCOPY(vEdge, prow, m+1); vEdge[0] = 0; #endif lp->bfp_ftran_normal(lp, vEdge, NULL); } /* Deal with the variable entering the basis to become a new leaving candidate */ cEdge = lp->edgeVector[exitcol]; rw = w[rownr]; hold = 1 / rw; lp->edgeVector[colnr] = (hold*hold) * cEdge; #ifdef Paranoia if(lp->edgeVector[colnr] <= lp->epsmachine) report(lp, errlevel, "updatePricer: Invalid dual norm %g at entering index %d - iteration %.0f\n", lp->edgeVector[colnr], rownr, (double) (lp->total_iter+lp->current_iter)); #endif /* Then loop over all basic variables, but skip the leaving row */ for(i = 1; i <= m; i++) { if(i == rownr) continue; targetcol = lp->var_basic[i]; hold = w[i]; if(hold == 0) continue; hold /= rw; if(fabs(hold) < lp->epsmachine) continue; newEdge = &(lp->edgeVector[targetcol]); *newEdge += (hold*hold) * cEdge; if(isDEVEX) { if((*newEdge) > DEVEX_RESTARTLIMIT) { forceRefresh = TRUE; break; } } else { *newEdge -= 2*hold*vEdge[i]; #ifdef xxApplySteepestEdgeMinimum SETMAX(*newEdge, hold*hold+1); /* Kludge; use the primal lower bound */ #else if(*newEdge <= 0) { report(lp, errlevel, "updatePricer: Invalid dual norm %g at index %d - iteration %.0f\n", *newEdge, i, (double) (lp->total_iter+lp->current_iter)); forceRefresh = TRUE; break; } #endif } } } /* Price norms for the primal simplex - the non-basic columns */ else { REAL *vTemp = NULL, *vAlpha = NULL, cAlpha; int *coltarget; ok = allocREAL(lp, &vTemp, m+1, TRUE) && allocREAL(lp, &vAlpha, n+1, TRUE); if(!ok) return( ok ); /* Check if we have strategy fallback for the primal */ if(!isDEVEX) isDEVEX = is_piv_mode(lp, PRICE_PRIMALFALLBACK); /* Initialize column target array */ coltarget = (int *) mempool_obtainVector(lp->workarrays, lp->sum+1, sizeof(*coltarget)); ok = get_colIndexA(lp, SCAN_SLACKVARS+SCAN_USERVARS+USE_NONBASICVARS, coltarget, FALSE); if(!ok) { mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE); return( ok ); } /* Don't need to compute cross-products with DEVEX */ if(!isDEVEX) { ok = allocREAL(lp, &vEdge, n+1, TRUE); if(!ok) return( ok ); /* Compute v and then N'v */ MEMCOPY(vTemp, w, m+1); bsolve(lp, -1, vTemp, NULL, lp->epsmachine*DOUBLEROUND, 0.0); vTemp[0] = 0; prod_xA(lp, coltarget, vTemp, NULL, lp->epsmachine, 0.0, vEdge, NULL, MAT_ROUNDDEFAULT); } /* Compute Sigma and then Alpha */ bsolve(lp, rownr, vTemp, NULL, 0*DOUBLEROUND, 0.0); vTemp[0] = 0; prod_xA(lp, coltarget, vTemp, NULL, lp->epsmachine, 0.0, vAlpha, NULL, MAT_ROUNDDEFAULT); mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE); /* Update the squared steepest edge norms; first store some constants */ cEdge = lp->edgeVector[colnr]; cAlpha = vAlpha[colnr]; /* Deal with the variable leaving the basis to become a new entry candidate */ hold = 1 / cAlpha; lp->edgeVector[exitcol] = (hold*hold) * cEdge; #ifdef Paranoia if(lp->edgeVector[exitcol] <= lp->epsmachine) report(lp, errlevel, "updatePricer: Invalid primal norm %g at leaving index %d - iteration %.0f\n", lp->edgeVector[exitcol], exitcol, (double) (lp->total_iter+lp->current_iter)); #endif /* Then loop over all non-basic variables, but skip the entering column */ for(i = 1; i <= lp->sum; i++) { if(lp->is_basic[i] || (i == colnr)) continue; hold = vAlpha[i]; if(hold == 0) continue; hold /= cAlpha; if(fabs(hold) < lp->epsmachine) continue; newEdge = &(lp->edgeVector[i]); *newEdge += (hold*hold) * cEdge; if(isDEVEX) { if((*newEdge) > DEVEX_RESTARTLIMIT) { forceRefresh = TRUE; break; } } else { *newEdge -= 2*hold*vEdge[i]; #ifdef ApplySteepestEdgeMinimum SETMAX(*newEdge, hold*hold+1); #else if(*newEdge < 0) { report(lp, errlevel, "updatePricer: Invalid primal norm %g at index %d - iteration %.0f\n", *newEdge, i, (double) (lp->total_iter+lp->current_iter)); if(lp->spx_trace) report(lp, errlevel, "Error detail: (RelAlpha=%g, vEdge=%g, cEdge=%g)\n", hold, vEdge[i], cEdge); forceRefresh = TRUE; break; } #endif } } FREE(vAlpha); FREE(vTemp); } FREE(vEdge); freeWeights(w); if(forceRefresh) ok = restartPricer(lp, AUTOMATIC); else ok = TRUE; return( ok ); }