当前位置: 首页 > news >正文

长春火车站建在哪里志鸿优化设计

长春火车站建在哪里,志鸿优化设计,最新常州网页制作招聘,北京做手机网站的公司哪家好绘画文字 绘画文字主要包括转换编码(主要是中文),解析字形(点线或image)和实际渲染三个步骤.在该过程中,解析字形和实际渲染均是耗时步骤. Skia缓存解析文字的结果.在中文字较多,使用多种字体,绘画风格(粗/斜体)有变化时,该缓存会很大,因此Skia文字,限制了缓存的内存. 1,SkP…绘画文字 绘画文字主要包括转换编码(主要是中文),解析字形(点线或image)和实际渲染三个步骤.在该过程中,解析字形和实际渲染均是耗时步骤. Skia缓存解析文字的结果.在中文字较多,使用多种字体,绘画风格(粗/斜体)有变化时,该缓存会很大,因此Skia文字,限制了缓存的内存. 1,SkPaint 绘画文字与SkPaint的属性很相关,先回头看下SkPaint相关的属性 class SkPaint { privateSkTypeface* fTypeface;//字体SkPathEffect* fPathEffect;//绘画路径效果SkShader* fShader;//取色器SkXfermode* fXfermode;//混合模式,类似OpenGL里面的Blend设置SkColorFilter* fColorFilter;//绘画图像时,自定义采样图像函数时使用SkMaskFilter* fMaskFilter;//绘画路径时,按有无像素做进一步自定义改进处理时使用SkRasterizer* fRasterizer;//绘画路径时自定义生成像素点的算法时使用SkDrawLooper* fLooper;//循环绘画,SkCanvas里面的第二重循环,一般不用关注SkImageFilter* fImageFilter;//SkCanvas的第一重循环,绘画后后处理,一般不用关注SkAnnotation* fAnnotation;//暂时没用到的属性SkScalar fTextSize;//文字大小SkScalar fTextScaleX;//文字水平方向上的拉伸,仅用于PDF绘画SkScalar fTextSkewX;//文字横向扭曲度,仅用于PDF绘画SkColor fColor;//纯色,在fShader为空时使用SkScalar fWidth;//带边界时(kStroke_Style/kStrokeAndFill_Style)生效,边界的宽度SkScalar fMiterLimit;//drawPath时,连接各个路径片断时,期望圆滑连接阈值,Join类型为默认的kMiter_Join时无效//一组不超过32位的属性union {struct {//所有这些位域加起来应达到32个unsigned fFlags : 16;//包含所有的0/1二值属性://注释块kAntiAlias_Flag 0x01,//是否抗锯齿kDither_Flag 0x04,//是否处理抖动kUnderlineText_Flag 0x08,//是否绘画文字下划线kStrikeThruText_Flag 0x10,//目前未看到其作用kFakeBoldText_Flag 0x20,kLinearText_Flag 0x40,kSubpixelText_Flag 0x80,//文字像素精确采样kDevKernText_Flag 0x100kLCDRenderText_Flag 0x200kEmbeddedBitmapText_Flag 0x400,kAutoHinting_Flag 0x800,kVerticalText_Flag 0x1000,//是否竖向绘画文字kGenA8FromLCD_Flag 0x2000,kDistanceFieldTextTEMP_Flag 0x4000,kAllFlags 0xFFFF//注释块unsigned fTextAlign : 2;//完文字对齐方式,取值如下://注释起enum Align {kLeft_Align,//左对齐kCenter_Align,//居中kRight_Align,//右对齐};//注释尾unsigned fCapType : 2;//边界连接类型,分无连接,圆角连接,半方形连接unsigned fJoinType : 2;//Path片断连接类型unsigned fStyle : 2;//绘画模式,填充边界/区域//注释起enum Style {kFill_Style, //填充区域kStroke_Style,//绘画边界kStrokeAndFill_Style,//填充区域并绘画边界};//注释尾unsigned fTextEncoding : 2;//文字编码格式,支持如下几种enum TextEncoding {kUTF8_TextEncoding,//utf-8,默认格式kUTF16_TextEncoding,kUTF32_TextEncoding,kGlyphID_TextEncoding};unsigned fHinting : 2;unsigned fFilterLevel : 2;//在绘画图像时提到的采样质量要求//unsigned fFreeBits:2;};uint32_t fBitfields;};uint32_t fDirtyBits;//记录改变了哪些属性,以便更新相关缓存 };2,字体绘画基本流程 SkCanvas,绘画文字和下划线 SkDraw,两个绘画方式: (1)按路径解析文字,然后绘画路径,缓存路径(drawText_asPaths). void SkDraw::drawText_asPaths(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint paint) const {SkDEBUGCODE(this-validate();)SkTextToPathIter iter(text, byteLength, paint, true);SkMatrix matrix;matrix.setScale(iter.getPathScale(), iter.getPathScale());matrix.postTranslate(x, y);const SkPath* iterPath;SkScalar xpos, prevXPos 0;while (iter.next(iterPath, xpos)) {matrix.postTranslate(xpos - prevXPos, 0);if (iterPath) {const SkPaint pnt iter.getPaint();if (fDevice) {fDevice-drawPath(*this, *iterPath, pnt, matrix, false);} else {this-drawPath(*iterPath, pnt, matrix, false);}}prevXPos xpos;} }(2)按Mask(32*32的A8图片)解析文字,然后绘画模板,缓存模板. SkDrawCacheProc glyphCacheProc paint.getDrawCacheProc(); SkAutoGlyphCache autoCache(paint, fDevice-fLeakyProperties, fMatrix); SkGlyphCache* cache autoCache.getCache(); //转变起点 {SkPoint loc;fMatrix-mapXY(x, y, loc);x loc.fX;y loc.fY; } //要先测量 if (paint.getTextAlign() ! SkPaint::kLeft_Align) {SkVector stop;measure_text(cache, glyphCacheProc, text, byteLength, stop);SkScalar stopX stop.fX;SkScalar stopY stop.fY;if (paint.getTextAlign() SkPaint::kCenter_Align) {stopX SkScalarHalf(stopX);stopY SkScalarHalf(stopY);}x - stopX;y - stopY; } const char* stop text byteLength; SkAAClipBlitter aaBlitter; SkAutoBlitterChoose blitterChooser; SkBlitter* blitter NULL; if (needsRasterTextBlit(*this)) {blitterChooser.choose(*fBitmap, *fMatrix, paint);blitter blitterChooser.get();if (fRC-isAA()) {aaBlitter.init(blitter, fRC-aaRgn());blitter aaBlitter;} } SkAutoKern autokern; SkDraw1Glyph d1g; SkDraw1Glyph::Proc proc d1g.init(this, blitter, cache, paint); SkFixed fxMask ~0; SkFixed fyMask ~0; if (cache-isSubpixel()) {SkAxisAlignment baseline SkComputeAxisAlignmentForHText(*fMatrix);if (kX_SkAxisAlignment baseline) {fyMask 0;d1g.fHalfSampleY SK_FixedHalf;} else if (kY_SkAxisAlignment baseline) {fxMask 0;d1g.fHalfSampleX SK_FixedHalf;} } SkFixed fx SkScalarToFixed(x) d1g.fHalfSampleX; SkFixed fy SkScalarToFixed(y) d1g.fHalfSampleY; while (text stop) {const SkGlyph glyph glyphCacheProc(cache, text, fx fxMask, fy fyMask);fx autokern.adjust(glyph);if (glyph.fWidth) {proc(d1g, fx, fy, glyph);}fx glyph.fAdvanceX;fy glyph.fAdvanceY; }cacheProc是由SkPaint::getDrawCacheProc产生,用来翻译符编码的函数: SkDrawCacheProc SkPaint::getDrawCacheProc() const {static const SkDrawCacheProc gDrawCacheProcs[] {sk_getMetrics_utf8_00,sk_getMetrics_utf16_00,sk_getMetrics_utf32_00,sk_getMetrics_glyph_00,sk_getMetrics_utf8_xy,sk_getMetrics_utf16_xy,sk_getMetrics_utf32_xy,sk_getMetrics_glyph_xy};unsigned index this-getTextEncoding();if (fFlags kSubpixelText_Flag) {index 4;}SkASSERT(index SK_ARRAY_COUNT(gDrawCacheProcs));return gDrawCacheProcs[index]; }SkGlyphCache:缓存解析字形的结果. SkScalerContext:负责解析字形,有多种实现.安卓中是用FreeType:SkScalerContext_FreeType.主要是generateImage和generatePath两个方法: generateImage: void SkScalerContext_FreeType::generateImage(const SkGlyph glyph) {SkAutoMutexAcquire ac(gFTMutex);FT_Error err;if (this-setupSize()) {goto ERROR;}err FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);if (err ! 0) {SkDEBUGF((SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:%d width:%d height:%d rb:%d flags:%d) returned 0x%x\n,glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeight, glyph.rowBytes(), fLoadGlyphFlags, err));ERROR:memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);return;}emboldenIfNeeded(fFace, fFace-glyph);generateGlyphImage(fFace, glyph); } void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGlyph glyph) {const bool doBGR SkToBool(fRec.fFlags SkScalerContext::kLCD_BGROrder_Flag);const bool doVert SkToBool(fRec.fFlags SkScalerContext::kLCD_Vertical_Flag);switch ( face-glyph-format ) {case FT_GLYPH_FORMAT_OUTLINE: {FT_Outline* outline face-glyph-outline;FT_BBox bbox;FT_Bitmap target;int dx 0, dy 0;if (fRec.fFlags SkScalerContext::kSubpixelPositioning_Flag) {dx SkFixedToFDot6(glyph.getSubXFixed());dy SkFixedToFDot6(glyph.getSubYFixed());//因为freetype-y-goes-up和skia-y-goes-down,反向dydy -dy;}FT_Outline_Get_CBox(outline, bbox);//真正想为Subpixel做的是//offset(dx, dy)//compute_bounds//offset(bbox !63)//但这是两个调用offset,因此如下,只需一个调用offset即可实现相同目的.FT_Outline_Translate(outline, dx - ((bbox.xMin dx) ~63), dy - ((bbox.yMin dy) ~63));if (SkMask::kLCD16_Format glyph.fMaskFormat) {FT_Render_Glyph(face-glyph, doVert ? FT_RENDER_MODE_LCD_V : FT_RENDER_MODE_LCD);SkMask mask;glyph.toMask(mask);if (fPreBlend.isApplicable()) {copyFT2LCD16true(face-glyph-bitmap, mask, doBGR,fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);} else {copyFT2LCD16false(face-glyph-bitmap, mask, doBGR,fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);}} else {target.width glyph.fWidth;target.rows glyph.fHeight;target.pitch glyph.rowBytes();target.buffer reinterpret_castuint8_t*(glyph.fImage);target.pixel_mode compute_pixel_mode( (SkMask::Format)fRec.fMaskFormat);target.num_grays 256;memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);FT_Outline_Get_Bitmap(face-glyph-library, outline, target);}} break;case FT_GLYPH_FORMAT_BITMAP: {FT_Pixel_Mode pixel_mode static_castFT_Pixel_Mode(face-glyph-bitmap.pixel_mode);SkMask::Format maskFormat static_castSkMask::Format(glyph.fMaskFormat);//假定没有其他格式.SkASSERT(FT_PIXEL_MODE_MONO pixel_mode ||FT_PIXEL_MODE_GRAY pixel_mode ||FT_PIXEL_MODE_BGRA pixel_mode);//这些是此ScalerContext应请求的唯一格式.SkASSERT(SkMask::kBW_Format maskFormat ||SkMask::kA8_Format maskFormat ||SkMask::kARGB32_Format maskFormat ||SkMask::kLCD16_Format maskFormat);if (fRec.fFlags SkScalerContext::kEmbolden_Flag !(face-style_flags FT_STYLE_FLAG_BOLD)){FT_GlyphSlot_Own_Bitmap(face-glyph);FT_Bitmap_Embolden(face-glyph-library, face-glyph-bitmap, kBitmapEmboldenStrength, 0);}//如果不需要缩放,则直接复制字形位图.if (glyph.fWidth face-glyph-bitmap.width glyph.fHeight face-glyph-bitmap.rows glyph.fTop -face-glyph-bitmap_top glyph.fLeft face-glyph-bitmap_left){SkMask dstMask;glyph.toMask(dstMask);copyFTBitmap(face-glyph-bitmap, dstMask);break;}//否则,缩放位图.复制FT_Bitmap到SkBitmap(A8或ARGB)中SkBitmap unscaledBitmap;unscaledBitmap.allocPixels(SkImageInfo::Make(face-glyph-bitmap.width, face-glyph-bitmap.rows, SkColorType_for_FTPixelMode(pixel_mode), kPremul_SkAlphaType));SkMask unscaledBitmapAlias;unscaledBitmapAlias.fImage reinterpret_castuint8_t*(unscaledBitmap.getPixels());unscaledBitmapAlias.fBounds.set(0, 0, unscaledBitmap.width(), unscaledBitmap.height());unscaledBitmapAlias.fRowBytes unscaledBitmap.rowBytes();unscaledBitmapAlias.fFormat SkMaskFormat_for_SkColorType(unscaledBitmap.colorType());copyFTBitmap(face-glyph-bitmap, unscaledBitmapAlias);//除非字形的掩码是BW或LCD,否则在位图中,包装字形的掩码.BW需要一个A8目标来调整,然后可下采样它.LCD应使用4xA8目标,然后下采样它.为简单起见,LCD使用A8并复制它.int bitmapRowBytes 0;if (SkMask::kBW_Format ! maskFormat SkMask::kLCD16_Format ! maskFormat) {bitmapRowBytes glyph.rowBytes();}SkBitmap dstBitmap;dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight, SkColorType_for_SkMaskFormat(maskFormat), kPremul_SkAlphaType), bitmapRowBytes);if (SkMask::kBW_Format maskFormat || SkMask::kLCD16_Format maskFormat) {dstBitmap.allocPixels();} else {dstBitmap.setPixels(glyph.fImage);}//缩放unscaledBitmap进dstBitmapSkCanvas canvas(dstBitmap);canvas.clear(SK_ColorTRANSPARENT);canvas.scale(SkIntToScalar(glyph.fWidth) / SkIntToScalar(face-glyph-bitmap.width),SkIntToScalar(glyph.fHeight) / SkIntToScalar(face-glyph-bitmap.rows));SkPaint paint;paint.setFilterLevel(SkPaint::kMedium_FilterLevel);canvas.drawBitmap(unscaledBitmap, 0, 0, paint);//如果目标是BW或LCD,则从A8转换.if (SkMask::kBW_Format maskFormat) {//复制A8的dstBitmap进A1的glyph.fImage中.SkMask dstMask;glyph.toMask(dstMask);packA8ToA1(dstMask, dstBitmap.getAddr8(0, 0), dstBitmap.rowBytes());} else if (SkMask::kLCD16_Format maskFormat) {//复制A8的dstBitmap进LCD16的glyph.fImage中.uint8_t* src dstBitmap.getAddr8(0, 0);uint16_t* dst reinterpret_castuint16_t*(glyph.fImage);for (int y dstBitmap.height(); y -- 0;) {for (int x 0; x dstBitmap.width(); x) {dst[x] grayToRGB16(src[x]);}dst (uint16_t*)((char*)dst glyph.rowBytes());src dstBitmap.rowBytes();}}} break;default:SkDEBUGFAIL(unknown glyph format);memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);return;}//过去总是在预USE_COLOR_LUMINANCE,但有了colorlum,它是可选的 #if defined(SK_GAMMA_APPLY_TO_A8)if (SkMask::kA8_Format glyph.fMaskFormat fPreBlend.isApplicable()) {uint8_t* SK_RESTRICT dst (uint8_t*)glyph.fImage;unsigned rowBytes glyph.rowBytes();for (int y glyph.fHeight - 1; y 0; --y) {for (int x glyph.fWidth - 1; x 0; --x) {dst[x] fPreBlend.fG[dst[x]];}dst rowBytes;}} #endif }generatePath: void SkScalerContext_FreeType::generatePath(const SkGlyph glyph, SkPath* path) {SkAutoMutexAcquire ac(gFTMutex);SkASSERT(glyph path);if (this-setupSize()) {path-reset();return;}uint32_t flags fLoadGlyphFlags;flags | FT_LOAD_NO_BITMAP; //忽略嵌入的位图,这样就可确保得到轮廓flags ~FT_LOAD_RENDER; //不要扫描转换(只想要轮廓)FT_Error err FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flags);if (err ! 0) {SkDEBUGF((SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n, glyph.getGlyphID(fBaseGlyphCount), flags, err));path-reset();return;}emboldenIfNeeded(fFace, fFace-glyph);generateGlyphPath(fFace, path);//FreeType的路径原点总是是水平布局原点.如果需要,偏移路径,使其相对垂直原点.if (fRec.fFlags SkScalerContext::kVertical_Flag) {FT_Vector vector;vector.x fFace-glyph-metrics.vertBearingX - fFace-glyph-metrics.horiBearingX;vector.y -fFace-glyph-metrics.vertBearingY - fFace-glyph-metrics.horiBearingY;FT_Vector_Transform(vector, fMatrix22);path-offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y));} }3,字体缓存管理 SkTypeface是Skia中的字体类,对应可有多种解析字体库实现. 因为安卓上面使用的是FreeType,因此也只讲FreeType分支. FreeType的用法可参考:链接 创建字体代码如下: SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) {return SkFontHost::CreateTypefaceFromStream(stream); } bool find_name_and_attributes(SkStream* stream, SkString* name, SkTypeface::Style* style, bool* isFixedPitch) {FT_Library library;if (FT_Init_FreeType(library)) {return false;}FT_Open_Args args;memset(args, 0, sizeof(args));const void* memoryBase stream-getMemoryBase();FT_StreamRec streamRec;if (NULL ! memoryBase) {args.flags FT_OPEN_MEMORY;args.memory_base (const FT_Byte*)memoryBase;args.memory_size stream-getLength();} else {memset(streamRec, 0, sizeof(streamRec));streamRec.size stream-getLength();streamRec.descriptor.pointer stream;streamRec.read sk_stream_read;streamRec.close sk_stream_close;args.flags FT_OPEN_STREAM;args.stream streamRec;}FT_Face face;if (FT_Open_Face(library, args, 0, face)) {FT_Done_FreeType(library);return false;}int tempStyle SkTypeface::kNormal;if (face-style_flags FT_STYLE_FLAG_BOLD) {tempStyle | SkTypeface::kBold;}if (face-style_flags FT_STYLE_FLAG_ITALIC) {tempStyle | SkTypeface::kItalic;}if (name) {name-set(face-family_name);}if (style) {*style (SkTypeface::Style) tempStyle;}if (isFixedPitch) {*isFixedPitch FT_IS_FIXED_WIDTH(face);}FT_Done_Face(face);FT_Done_FreeType(library);return true; }对安卓,初化系统时,在预加载时就解析所有字体文件,按SkFaceRec包装,并保存为一个全局链表.见(frameworks/base/graphic和frameworks/base/core/jni目录下面的代码) public class Typeface {private static void init() {//加载字体配置并初化Minikin状态File systemFontConfigLocation getSystemFontConfigLocation();File configFilename new File(systemFontConfigLocation, FONTS_CONFIG);try {FileInputStream fontsIn new FileInputStream(configFilename);FontListParser.Config fontConfig FontListParser.parse(fontsIn);ListFontFamily familyList new ArrayListFontFamily();//注意,默认字体总是在回退列表中;这是对预Minikin行为的增强.for (int i 0; i fontConfig.families.size(); i) {Family f fontConfig.families.get(i);if (i 0 || f.name null) {familyList.add(makeFamilyFromParsed(f));}}sFallbackFonts familyList.toArray(new FontFamily[familyList.size()]);setDefault(Typeface.createFromFamilies(sFallbackFonts));MapString, Typeface systemFonts new HashMapString, Typeface();for (int i 0; i fontConfig.families.size(); i) {Typeface typeface;Family f fontConfig.families.get(i);if (f.name ! null) {if (i 0) {//第一项是默认字体;不必复制相应的FontFamily.typeface sDefaultTypeface;} else {FontFamily fontFamily makeFamilyFromParsed(f);FontFamily[] families { fontFamily };typeface Typeface.createFromFamiliesWithDefault(families);}systemFonts.put(f.name, typeface);}}for (FontListParser.Alias alias : fontConfig.aliases) {Typeface base systemFonts.get(alias.toName);Typeface newFace base;int weight alias.weight;if (weight ! 400) {newFace new Typeface(nativeCreateWeightAlias(base.native_instance, weight));}systemFonts.put(alias.name, newFace);}sSystemFontMap systemFonts;} catch (RuntimeException e) {Log.w(TAG, Didnt create default family (most likely, non-Minikin build), e);//TODO:在非Minikin时候正常,仅Minikin时,删除或出错} catch (FileNotFoundException e) {Log.e(TAG, Error opening configFilename);} catch (IOException e) {Log.e(TAG, Error reading configFilename);} catch (XmlPullParserException e) {Log.e(TAG, XML parse exception for configFilename);}}static {init();//安装公开API中公开的默认值和字体DEFAULT create((String) null, 0);DEFAULT_BOLD create((String) null, Typeface.BOLD);SANS_SERIF create(sans-serif, 0);SERIF create(serif, 0);MONOSPACE create(monospace, 0);sDefaults new Typeface[] {DEFAULT,DEFAULT_BOLD,create((String) null, Typeface.ITALIC),create((String) null, Typeface.BOLD_ITALIC),};} }SkTypeface记录一个字体的id,使用时,到链表中查出相关的字体. 一个字体和风格,建一个SkGlyphCache缓存,内含一个SkScalerContext和一个SkGlyph的哈希表,SkGlyph缓存字体中解析字出来的位图. 此有内存容量限制,超过容量时,会清理之前缓存的位图.Hash冲突时,直接生成新字形替换原字形. 限制缓存的内存宏详见:src/core/SkGlyphCache_Globals.h.和include/core/SkUserConfig.h中的SK_DEFAULT_FONT_CACHE_LIMIT宏 struct SkGlyph {void* fImage;SkPath* fPath;SkFixed fAdvanceX, fAdvanceY;uint32_t fID;uint16_t fWidth, fHeight;int16_t fTop, fLeft;void* fDistanceField;uint8_t fMaskFormat;int8_t fRsbDelta, fLsbDelta; //自动调整字距,时使用 };绘画字体只绘边界,或缓存位图机制不好处理时,按点线解析字体,构成SkPath,也要缓存.
http://www.yutouwan.com/news/422346/

相关文章:

  • 电商网站前端架构设计跨境商城网站开发
  • 河南网站建设app开发微网站怎么做的好
  • 海南海口网站开发公司路由器设置网站
  • 怎么自己搭建网站网站备案工作
  • 建设银行唐山分行网站天津网站建设案例
  • 大型 视频网站开发微网页制作模板
  • 沧州市网站建设价格无极官方网站
  • 网站开发样例广西电力工程建设公司网站
  • iis网站发布教程青岛外贸推广
  • 建设英文网站费用搜狐快站官网
  • 网站推广包括网站怎做百度代码统计
  • php做网站怎么样做儿童业态招商要去哪些网站
  • 国家精品课程建设工作网站公司网站介绍模板 html
  • 做视频播放网站 赚钱怎样学好网站开发
  • 网站404页面的作用火车头 wordpress4.8
  • 劳动保障局瓯海劳务市场和做网站商城网站建设公司哪家好
  • 平罗门户网站建设全国建筑企业资质查询系统官网
  • 自营店网站建设外贸网站怎么找客户
  • 合肥做网站优化公司aspnet东莞网站建设多少钱
  • 只有asp网站代码可以重新编译吗用adsl做网站备案
  • 自己做服务器网站公司网站是别人做的如何换logo
  • 微信小网站是怎么做的安徽全过程网站搭建案例
  • 网站建设教程在线观看wordpress禁止右键
  • 医院做网站是最简单的前端吗电商网站如何优化
  • 网站系统升级维护需要多长时间网站建设平台软件哪个好用
  • 怎么做网站调查表电子商务方案设计案例
  • 建设网站需要的ftp资源长沙营销企业网站建设
  • php网站开发工程师招聘会在线动画手机网站模板
  • 延吉网站网站建设软件开发技术方案模板
  • 瑞安市建设工程质量监督站网站瑞安做网站多少钱