当前位置: 首页 > 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.lebaoying.cn/news/36924.html

相关文章:

  • 廊坊开发网站公司枣强网站建设
  • 中药材天地网做中药零售网站wordpress打不开自定义
  • 网站主机 流量视频拍摄脚本模板
  • 冠县网站建设费用wordpress 安装语言设置中文
  • 聊城网站开发公司建工网站
  • 什么行业最需要网站建设网站制作属于什么专业
  • 站长之家网站流量查询租域名和服务器要多少钱
  • 安卓手机如何做网站win10 wordpress安装
  • seo优化文章网站网站现在如何做推广
  • 绵阳的网站建设公司成品网站源码的优化技巧
  • 百度收录哪些网站吗天津建设执业资格注册中心网站
  • 做公司网站需要什么程序如何选择做网站
  • 做怎样的企业网站东莞市网站开发
  • 崇信县门户网站官网郑州企业网站托管公司
  • 规划网站总结网站推广策略与问题分析
  • wordpress 做影视站wordpress 博客搬家
  • 网站建设服务器的配置wordpress简历
  • 个人网站可以做淘宝客惠州市住房和城乡规划建设局官方网站
  • 江西网站制作公司哪些企业需要网络推广
  • 一个设计网站多少钱长沙app定制开发
  • 山东济宁网站建设西安网站建设软件
  • 有哪些网站建设工作注册一个公司的流程
  • 公司网页网站建设ppt模板下载义乌市建设局官方网站
  • 网站设计风格有哪些计算机网站开发图片
  • 我的世界查询建筑网站网站建设 今晟网络
  • 网站怎么做appWordPress tag 分类
  • 百度广告投放平台广州seo服务
  • 重庆网站建设公司是什么意思icp备案有效期几年
  • 比特币网站建设网站开发的技术路线
  • 那个网站做h5好有前景的网站建设