void DisplayObject::computeBoundsForTransformedRect(number_t xmin, number_t xmax, number_t ymin, number_t ymax, int32_t& outXMin, int32_t& outYMin, uint32_t& outWidth, uint32_t& outHeight, const MATRIX& m) const { //As the transformation is arbitrary we have to check all the four vertices number_t coords[8]; m.multiply2D(xmin,ymin,coords[0],coords[1]); m.multiply2D(xmin,ymax,coords[2],coords[3]); m.multiply2D(xmax,ymax,coords[4],coords[5]); m.multiply2D(xmax,ymin,coords[6],coords[7]); //Now find out the minimum and maximum that represent the complete bounding rect number_t minx=coords[6]; number_t maxx=coords[6]; number_t miny=coords[7]; number_t maxy=coords[7]; for(int i=0;i<6;i+=2) { if(coords[i]<minx) minx=coords[i]; else if(coords[i]>maxx) maxx=coords[i]; if(coords[i+1]<miny) miny=coords[i+1]; else if(coords[i+1]>maxy) maxy=coords[i+1]; } outXMin=minx; outYMin=miny; outWidth=ceil(maxx-minx); outHeight=ceil(maxy-miny); }
bool DisplayObject::getBounds(number_t& xmin, number_t& xmax, number_t& ymin, number_t& ymax, const MATRIX& m) const { if(!isConstructed()) return false; bool ret=boundsRect(xmin,xmax,ymin,ymax); if(ret) { number_t tmpX[4]; number_t tmpY[4]; m.multiply2D(xmin,ymin,tmpX[0],tmpY[0]); m.multiply2D(xmax,ymin,tmpX[1],tmpY[1]); m.multiply2D(xmax,ymax,tmpX[2],tmpY[2]); m.multiply2D(xmin,ymax,tmpX[3],tmpY[3]); auto retX=minmax_element(tmpX,tmpX+4); auto retY=minmax_element(tmpY,tmpY+4); xmin=*retX.first; xmax=*retX.second; ymin=*retY.first; ymax=*retY.second; } return ret; }
void TokenContainer::FromShaperecordListToShapeVector(const std::vector<SHAPERECORD>& shapeRecords, tokensVector& tokens, const std::list<FILLSTYLE>& fillStyles, const MATRIX& matrix) { Vector2 cursor; unsigned int color0=0; unsigned int color1=0; ShapesBuilder shapesBuilder; for(unsigned int i=0; i<shapeRecords.size(); i++) { const SHAPERECORD* cur=&shapeRecords[i]; if(cur->TypeFlag) { if(cur->StraightFlag) { Vector2 p1(matrix.multiply2D(cursor)); cursor.x += cur->DeltaX; cursor.y += cur->DeltaY; Vector2 p2(matrix.multiply2D(cursor)); if(color0) shapesBuilder.extendFilledOutlineForColor(color0,p1,p2); if(color1) shapesBuilder.extendFilledOutlineForColor(color1,p1,p2); } else { Vector2 p1(matrix.multiply2D(cursor)); cursor.x += cur->ControlDeltaX; cursor.y += cur->ControlDeltaY; Vector2 p2(matrix.multiply2D(cursor)); cursor.x += cur->AnchorDeltaX; cursor.y += cur->AnchorDeltaY; Vector2 p3(matrix.multiply2D(cursor)); if(color0) shapesBuilder.extendFilledOutlineForColorCurve(color0,p1,p2,p3); if(color1) shapesBuilder.extendFilledOutlineForColorCurve(color1,p1,p2,p3); } } else { if(cur->StateMoveTo) { cursor.x=cur->MoveDeltaX; cursor.y=cur->MoveDeltaY; } /* if(cur->StateLineStyle) { cur_path->state.validStroke=true; cur_path->state.stroke=cur->LineStyle; }*/ if(cur->StateFillStyle1) { color1=cur->FillStyle1; } if(cur->StateFillStyle0) { color0=cur->FillStyle0; } } } shapesBuilder.outputTokens(fillStyles, tokens); }
void TokenContainer::FromDefineMorphShapeTagToShapeVector(SystemState* sys,DefineMorphShapeTag *tag, tokensVector &tokens, uint16_t ratio) { LOG(LOG_NOT_IMPLEMENTED,"MorphShape currently ignores most morph settings and just displays the start/end shape. ID:"<<tag->getId()<<" ratio:"<<ratio); Vector2 cursor; unsigned int color0=0; unsigned int color1=0; unsigned int linestyle=0; const MATRIX matrix; ShapesBuilder shapesBuilder; // TODO compute SHAPERECORD entries based on ratio auto it = ratio == 65535 ? tag->EndEdges.ShapeRecords.begin() : tag->StartEdges.ShapeRecords.begin(); auto last = ratio == 65535 ? tag->EndEdges.ShapeRecords.end() : tag->StartEdges.ShapeRecords.end(); while (it != last) { const SHAPERECORD* cur=&(*it); it++; if(cur->TypeFlag) { if(cur->StraightFlag) { Vector2 p1(matrix.multiply2D(cursor)); cursor.x += cur->DeltaX; cursor.y += cur->DeltaY; Vector2 p2(matrix.multiply2D(cursor)); if(color0) shapesBuilder.extendFilledOutlineForColor(color0,p1,p2); if(color1) shapesBuilder.extendFilledOutlineForColor(color1,p1,p2); if(linestyle) shapesBuilder.extendStrokeOutline(linestyle,p1,p2); } else { Vector2 p1(matrix.multiply2D(cursor)); cursor.x += cur->ControlDeltaX; cursor.y += cur->ControlDeltaY; Vector2 p2(matrix.multiply2D(cursor)); cursor.x += cur->AnchorDeltaX; cursor.y += cur->AnchorDeltaY; Vector2 p3(matrix.multiply2D(cursor)); if(color0) shapesBuilder.extendFilledOutlineForColorCurve(color0,p1,p2,p3); if(color1) shapesBuilder.extendFilledOutlineForColorCurve(color1,p1,p2,p3); if(linestyle) shapesBuilder.extendStrokeOutlineCurve(linestyle,p1,p2,p3); } } else { if(cur->StateMoveTo) { cursor.x=cur->MoveDeltaX; cursor.y=cur->MoveDeltaY; } if(cur->StateLineStyle) { linestyle = cur->LineStyle; } if(cur->StateFillStyle1) { color1=cur->FillStyle1; } if(cur->StateFillStyle0) { color0=cur->FillStyle0; } } } tokens.clear(); shapesBuilder.outputMorphTokens(tag->MorphFillStyles.FillStyles,tag->MorphLineStyles.LineStyles2, tokens,ratio); }