tree edit_graphics_rep::graphical_select (double x, double y) { frame f= find_frame (); if (is_nil (f)) return tuple (); gr_selections sels; point p0 = point (x, y); point p = f (p0); sels= eb->graphical_select ((SI)p[0], (SI)p[1], 10*get_pixel_size ()); gs= sels; pts= array<point> (0); ci= array<point> (0); cgi= array<point> (0); gr0= empty_grid (); grid g= find_grid (); frame f2= find_frame (true); if (!is_nil (g) && !is_nil (f2)) { gr0= g; p = f2 (point (x, y)); int i, j, n= N(sels); for (i=0; i<n; i++) { array<point> pts2= sels[i]->pts; if (N(pts2)>0 && norm (pts2[0] - p) <= 10*get_pixel_size ()) pts= pts << pts2[0]; if (N(pts2)>1 && norm (pts2[1] - p) <= 10*get_pixel_size ()) pts= pts << pts2[1]; } double eps= get_pixel_size () / 10.0; for (i=0; i<n; i++) { for (j=0; j<n; j++) if (i<j) { curve c1= sels[i]->c; curve c2= sels[j]->c; if (!is_nil (c1) && !is_nil (c2)) ci= ci << intersection (c1, c2, p, eps); } } array<grid_curve> gc= g->get_curves_around (p0, 10*get_pixel_size (), f); //FIXME: Too slow for (i=0; i<N(gc); i++) { curve c= f2 (gc[i]->c); for (j=0; j<n; j++) if (!is_nil (sels[j]->c)) cgi= cgi << intersection (c, sels[j]->c, p, eps); } } return as_tree (sels); }
Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) return triangle_mesh; PoolVector<Vector3> faces; faces.resize(6); PoolVector<Vector3>::Write facesw = faces.write(); Rect2 final_rect = get_item_rect(); if (final_rect.size.x == 0 || final_rect.size.y == 0) return Ref<TriangleMesh>(); float pixel_size = get_pixel_size(); Vector2 vertices[4] = { (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size, (final_rect.position + final_rect.size) * pixel_size, (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size, final_rect.position * pixel_size, }; int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); if (axis != Vector3::AXIS_Z) { SWAP(x_axis, y_axis); for (int i = 0; i < 4; i++) { if (axis == Vector3::AXIS_Y) { vertices[i].y = -vertices[i].y; } else if (axis == Vector3::AXIS_X) { vertices[i].x = -vertices[i].x; } } } static const int indices[6] = { 0, 1, 2, 0, 2, 3 }; for (int j = 0; j < 6; j++) { int i = indices[j]; Vector3 vtx; vtx[x_axis] = vertices[i][0]; vtx[y_axis] = vertices[i][1]; facesw[j] = vtx; } facesw = PoolVector<Vector3>::Write(); triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); triangle_mesh->create(faces); return triangle_mesh; }
point edit_graphics_rep::adjust (point p) { frame f= find_frame (); grid g= find_grid (); if (!is_nil (g) && !is_nil (gr0) && (g != gr0 || p[0] != p_x || p[1] != p_y)) { graphical_select (p[0], p[1]); g= gr0; p[0]= p_x; p[1]= p_y; } if (is_nil (g)) return p; point res; gr_selections sels= copy (gs); frame f2= find_frame (true); if (is_nil (f2)) return p; point fp= f2 (p); if ((tree) g != "empty_grid") { point q= g->find_point_around (p, snap_distance, f); point fq= f2 (q); if (norm (fq - fp) < snap_distance) { gr_selection sel; sel->type= "grid-point"; sel->p = fq; sel->dist= (SI) norm (fq - fp); sels << sel; } array<grid_curve> gc= g->get_curves_around (p, snap_distance, f); for (int i=0; i<N(gc); i++) { point fc= closest (f2 (gc[i]->c), fp); if (norm (fc - fp) < snap_distance) { gr_selection sel; sel->type= "grid-curve-point"; sel->p = fc; sel->dist= (SI) norm (fc - fp); sel->c = f2 (gc[i]->c); sels << sel; } } } double eps= get_pixel_size () / 10.0; gr_selection snap= snap_to_guide (fp, sels, eps); //cout << "Snap " << fp << " to " << snap << ", " << snap->p << "\n"; point snapped= f2[snap->p]; if (N(snapped) == 2) return snapped; return p; // FIXME: why can snapped be an invalid point? }
int Graph_Create( LCUI_Graph *graph, int w, int h ) { size_t size; if( w > 10000 || h > 10000 ) { _DEBUG_MSG("graph size is too large!"); abort(); } if( h <= 0 || w <= 0 ) { Graph_Free( graph ); return -1; } graph->bytes_per_pixel = get_pixel_size( graph->color_type ); graph->bytes_per_row = graph->bytes_per_pixel * w; size = graph->bytes_per_row * h; if( Graph_IsValid(graph) ) { /* 如果现有图形尺寸大于要创建的图形的尺寸,直接改尺寸即可 */ if( graph->mem_size >= size ) { if( (w != graph->w || h != graph->h) && graph->color_type == COLOR_TYPE_ARGB ) { Graph_FillAlpha( graph, 0 ); Graph_FillColor(graph, RGB(255,255,255)); } graph->w = w; graph->h = h; return 0; } Graph_Free( graph ); } graph->mem_size = size; graph->bytes = (uchar_t*)malloc( size ); if( !graph->bytes ) { graph->w = 0; graph->h = 0; return -2; } /* 默认全透明 */ if( graph->color_type == COLOR_TYPE_ARGB ) { Graph_FillAlpha( graph, 0 ); } graph->w = w; graph->h = h; return 0; }
void AnimatedSprite3D::_draw() { RID immediate = get_immediate(); VS::get_singleton()->immediate_clear(immediate); if (!frames.is_valid() || !frames->get_frame_count(animation) || frame<0 || frame>=frames->get_frame_count(animation)) { return; } Ref<Texture> texture = frames->get_frame(animation,frame); if (!texture.is_valid()) return; //no texuture no life Vector2 tsize = texture->get_size(); if (tsize.x==0 || tsize.y==0) return; Size2i s=tsize; Rect2i src_rect; src_rect.size=s; Point2i ofs=get_offset(); if (is_centered()) ofs-=s/2; Rect2i dst_rect(ofs,s); Rect2 final_rect; Rect2 final_src_rect; if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect)) return; if (final_rect.size.x==0 || final_rect.size.y==0) return; Color color=_get_color_accum(); color.a*=get_opacity(); float pixel_size=get_pixel_size(); Vector2 vertices[4]={ (final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size, (final_rect.pos+final_rect.size) * pixel_size, (final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size, final_rect.pos * pixel_size, }; Vector2 uvs[4]={ final_src_rect.pos / tsize, (final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize, (final_src_rect.pos+final_src_rect.size) / tsize, (final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize, }; if (is_flipped_h()) { SWAP(uvs[0],uvs[1]); SWAP(uvs[2],uvs[3]); } if (is_flipped_v()) { SWAP(uvs[0],uvs[3]); SWAP(uvs[1],uvs[2]); } Vector3 normal; int axis = get_axis(); normal[axis]=1.0; RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS); VS::get_singleton()->immediate_set_material(immediate,mat); VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid()); int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); if (axis!=Vector3::AXIS_Z) { SWAP(x_axis,y_axis); for(int i=0;i<4;i++) { //uvs[i] = Vector2(1.0,1.0)-uvs[i]; //SWAP(vertices[i].x,vertices[i].y); if (axis==Vector3::AXIS_Y) { vertices[i].y = - vertices[i].y; } else if (axis==Vector3::AXIS_X) { vertices[i].x = - vertices[i].x; } } } AABB aabb; for(int i=0;i<4;i++) { VS::get_singleton()->immediate_normal(immediate,normal); VS::get_singleton()->immediate_color(immediate,color); VS::get_singleton()->immediate_uv(immediate,uvs[i]); Vector3 vtx; vtx[x_axis]=vertices[i][0]; vtx[y_axis]=vertices[i][1]; VS::get_singleton()->immediate_vertex(immediate,vtx); if (i==0) { aabb.pos=vtx; aabb.size=Vector3(); } else { aabb.expand_to(vtx); } } set_aabb(aabb); VS::get_singleton()->immediate_end(immediate); }
void Sprite3D::_draw() { RID immediate = get_immediate(); VS::get_singleton()->immediate_clear(immediate); if (!texture.is_valid()) return; //no texuture no life Vector2 tsize = texture->get_size(); if (tsize.x==0 || tsize.y==0) return; Size2i s; Rect2i src_rect; if (region) { s=region_rect.size; src_rect=region_rect; } else { s = texture->get_size(); s=s/Size2i(hframes,vframes); src_rect.size=s; src_rect.pos.x+=(frame%hframes)*s.x; src_rect.pos.y+=(frame/hframes)*s.y; } Point2i ofs=get_offset(); if (is_centered()) ofs-=s/2; Rect2i dst_rect(ofs,s); Rect2 final_rect; Rect2 final_src_rect; if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect)) return; if (final_rect.size.x==0 || final_rect.size.y==0) return; Color color=_get_color_accum(); color.a*=get_opacity(); float pixel_size=get_pixel_size(); Vector2 vertices[4]={ (final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size, (final_rect.pos+final_rect.size) * pixel_size, (final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size, final_rect.pos * pixel_size, }; Vector2 uvs[4]={ final_src_rect.pos / tsize, (final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize, (final_src_rect.pos+final_src_rect.size) / tsize, (final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize, }; if (is_flipped_h()) { SWAP(uvs[0],uvs[1]); SWAP(uvs[2],uvs[3]); } if (is_flipped_v()) { SWAP(uvs[0],uvs[3]); SWAP(uvs[1],uvs[2]); } Vector3 normal; int axis = get_axis(); normal[axis]=1.0; RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS); VS::get_singleton()->immediate_set_material(immediate,mat); VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid()); int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); AABB aabb; for(int i=0;i<4;i++) { VS::get_singleton()->immediate_normal(immediate,normal); VS::get_singleton()->immediate_color(immediate,color); VS::get_singleton()->immediate_uv(immediate,uvs[i]); Vector3 vtx; vtx[x_axis]=vertices[i][x_axis]; vtx[y_axis]=vertices[i][y_axis]; VS::get_singleton()->immediate_vertex(immediate,vtx); if (i==0) { aabb.pos=vtx; aabb.size=Vector3(); } else { aabb.expand_to(vtx); } } set_aabb(aabb); VS::get_singleton()->immediate_end(immediate); }
point edit_graphics_rep::adjust (point p) { frame f= find_frame (); grid g= find_grid (); if (!is_nil (g) && !is_nil (gr0) && g!=gr0) { graphical_select (p[0], p[1]); g= gr0; } if (is_nil (g)) return p; else { point res; gr_selections sels= gs; frame f2= find_frame (true); if (!is_nil (f2)) { point fp= f2 (p); int i; if ((tree)g == "empty_grid") { if (N(pts)>0) res= pts[0]; for (i=0; i<N(pts); i++) { point sp= pts[i]; if (N(sp)>0 && norm (fp - sp) < 5*get_pixel_size ()) res= pts[i]; } int n= N(sels); for (i=0; i<n; i++) { point sp= sels[i]->p; if (N(res)==0 || (N(sp)>0 && norm (fp - sp) < 5*get_pixel_size () && norm (fp - sp) < norm (fp - res))) res= sels[i]->p; } } else if (!is_nil (f)) { res= f2 (g->find_point_around (p, 10*get_pixel_size (), f)); for (i=0; i<N(pts); i++) { point sp= pts[i]; if (N(sp)>0 && norm (fp - sp) < norm (fp - res)) res= pts[i]; } for (i=0; i<N(ci); i++) { point sp= ci[i]; if (N(sp)>0 && norm (fp - sp) < norm (fp - res)) res= ci[i]; } for (i=0; i<N(cgi); i++) { point sp= cgi[i]; if (N(sp)>0 && norm (fp - sp) < norm (fp - res)) res= cgi[i]; } //TODO: Adjusting by means on freely moving on surface of closed curves ; } if (N(res)>0) res= f2[res]; else res= p; } return res; } }
void Sprite3D::_draw() { RID immediate = get_immediate(); VS::get_singleton()->immediate_clear(immediate); if (!texture.is_valid()) return; //no texuture no life Vector2 tsize = texture->get_size(); if (tsize.x == 0 || tsize.y == 0) return; Size2i s; Rect2i src_rect; if (region) { s = region_rect.size; src_rect = region_rect; } else { s = texture->get_size(); s = s / Size2i(hframes, vframes); src_rect.size = s; src_rect.position.x += (frame % hframes) * s.x; src_rect.position.y += (frame / hframes) * s.y; } Point2i ofs = get_offset(); if (is_centered()) ofs -= s / 2; Rect2i dst_rect(ofs, s); Rect2 final_rect; Rect2 final_src_rect; if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect)) return; if (final_rect.size.x == 0 || final_rect.size.y == 0) return; Color color = _get_color_accum(); color.a *= get_opacity(); float pixel_size = get_pixel_size(); Vector2 vertices[4] = { (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size, (final_rect.position + final_rect.size) * pixel_size, (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size, final_rect.position * pixel_size, }; Vector2 src_tsize = tsize; // Properly setup UVs for impostor textures (AtlasTexture). Ref<AtlasTexture> atlas_tex = texture; if (atlas_tex != NULL) { src_tsize[0] = atlas_tex->get_atlas()->get_width(); src_tsize[1] = atlas_tex->get_atlas()->get_height(); } Vector2 uvs[4] = { final_src_rect.position / src_tsize, (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / src_tsize, (final_src_rect.position + final_src_rect.size) / src_tsize, (final_src_rect.position + Vector2(0, final_src_rect.size.y)) / src_tsize, }; if (is_flipped_h()) { SWAP(uvs[0], uvs[1]); SWAP(uvs[2], uvs[3]); } if (is_flipped_v()) { SWAP(uvs[0], uvs[3]); SWAP(uvs[1], uvs[2]); } Vector3 normal; int axis = get_axis(); normal[axis] = 1.0; RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS); VS::get_singleton()->immediate_set_material(immediate, mat); VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid()); int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); if (axis != Vector3::AXIS_Z) { SWAP(x_axis, y_axis); for (int i = 0; i < 4; i++) { //uvs[i] = Vector2(1.0,1.0)-uvs[i]; //SWAP(vertices[i].x,vertices[i].y); if (axis == Vector3::AXIS_Y) { vertices[i].y = -vertices[i].y; } else if (axis == Vector3::AXIS_X) { vertices[i].x = -vertices[i].x; } } } AABB aabb; for (int i = 0; i < 4; i++) { VS::get_singleton()->immediate_normal(immediate, normal); VS::get_singleton()->immediate_color(immediate, color); VS::get_singleton()->immediate_uv(immediate, uvs[i]); Vector3 vtx; vtx[x_axis] = vertices[i][0]; vtx[y_axis] = vertices[i][1]; VS::get_singleton()->immediate_vertex(immediate, vtx); if (i == 0) { aabb.position = vtx; aabb.size = Vector3(); } else { aabb.expand_to(vtx); } } set_aabb(aabb); VS::get_singleton()->immediate_end(immediate); }
/** * The size of a compressed block. * @return Size of a compressed block (4x4) in bytes. */ inline Uint16 get_block_size() const { return get_block_size(get_pixel_size()); }
void dib_img_writer(const char *contents, FILE *out, drawingStates *states, PU_BITMAPINFOHEADER BmiSrc, const unsigned char *BmpSrc, size_t size, bool assign_mono_colors_from_dc) { char *b64Bmp = NULL; size_t b64s; char *tmp = NULL; // Handle simple cases first, no treatment needed for them switch (BmiSrc->biCompression) { case U_BI_JPEG: b64Bmp = base64_encode(BmpSrc, size, &b64s); fprintf(out, "xlink:href=\"data:image/jpg;base64,"); break; case U_BI_PNG: b64Bmp = base64_encode(BmpSrc, size, &b64s); fprintf(out, "xlink:href=\"data:image/png;base64,"); break; } if (b64Bmp != NULL) { fprintf(out, "%s\" ", b64Bmp); free(b64Bmp); return; } // more complexe treatment, with conversion to png RGBBitmap convert_in; convert_in.size = size; convert_in.width = BmiSrc->biWidth; convert_in.height = BmiSrc->biHeight; convert_in.pixels = (RGBPixel *)BmpSrc; convert_in.bytewidth = BmiSrc->biWidth * 3; convert_in.bytes_per_pixel = 3; RGBBitmap convert_out; convert_out.pixels = NULL; const U_RGBQUAD *ct = NULL; U_RGBQUAD monoCt[2]; uint32_t width, height, colortype, numCt, invert; char *rgba_px = NULL; int dibparams; char *in; size_t img_size; RGBABitmap convert_inpng; // In any cases after that, we get a png blob fprintf(out, "xlink:href=\"data:image/png;base64,"); switch (BmiSrc->biCompression) { case U_BI_RLE8: convert_out = rle8ToRGB8(convert_in); break; case U_BI_RLE4: convert_out = rle4ToRGB(convert_in); break; } if (convert_out.pixels != NULL) { in = (char *)convert_out.pixels; img_size = convert_out.size; } else { in = (char *)convert_in.pixels; img_size = convert_in.size; } dibparams = e2s_get_DIB_params((PU_BITMAPINFO)BmiSrc, (const U_RGBQUAD **)&ct, &numCt, &width, &height, &colortype, &invert); // if enable to read header, then exit if (dibparams || width > MAX_BMP_WIDTH || height > MAX_BMP_HEIGHT) { free(convert_out.pixels); states->Error = true; return; } // check that what we will read in the DIB_to_RGBA conversion is actually // there size_t offset_check = (size_t)((float)width * (float)height * get_pixel_size(colortype)); if (((in + img_size) < in + offset_check)) { free(convert_out.pixels); states->Error = true; return; } if (colortype == U_BCBM_MONOCHROME) { if (assign_mono_colors_from_dc) { monoCt[0].Red = states->currentDeviceContext.text_red; monoCt[0].Green = states->currentDeviceContext.text_green; monoCt[0].Blue = states->currentDeviceContext.text_blue; monoCt[0].Reserved = 0xff; monoCt[1].Red = states->currentDeviceContext.bk_red; monoCt[1].Green = states->currentDeviceContext.bk_green; monoCt[1].Blue = states->currentDeviceContext.bk_blue; monoCt[1].Reserved = 0xff; // states->currentDeviceContext.bk_mode ? 0xff : 0; ct = monoCt; } } DIB_to_RGBA(in, ct, numCt, &rgba_px, width, height, colortype, numCt, invert); if (rgba_px != NULL) { convert_inpng.size = width * 4 * height; convert_inpng.width = width; convert_inpng.height = height; convert_inpng.pixels = (RGBAPixel *)rgba_px; convert_inpng.bytewidth = BmiSrc->biWidth * 3; convert_inpng.bytes_per_pixel = 3; rgb2png(&convert_inpng, &b64Bmp, &b64s); tmp = (char *)b64Bmp; b64Bmp = base64_encode((unsigned char *)b64Bmp, b64s, &b64s); free(convert_out.pixels); free(tmp); free(rgba_px); } if (b64Bmp != NULL) { fprintf(out, "%s\" ", b64Bmp); free(b64Bmp); } else { // transparent 5x5 px png fprintf(out, "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAABGdBTUEAA" "LGPC/xhBQAAAAZiS0dEAP8A/wD/" "oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+" "ABFREtOJX7FAkAAAAIdEVYdENvbW1lbnQA9syWvwAAAAxJREFUCNdjYKA" "TAAAAaQABwB3y+AAAAABJRU5ErkJggg==\" "); } }