From 4455d6156562d323e103d24b6245b74637914204 Mon Sep 17 00:00:00 2001 From: liangguirong Date: Fri, 13 Sep 2024 10:51:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=8B=B1=E6=96=87=E6=96=87?= =?UTF-8?q?=E6=A1=A3README=5FEN.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liangguirong --- README_EN.md | 320 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 README_EN.md diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 0000000..8cd88df --- /dev/null +++ b/README_EN.md @@ -0,0 +1,320 @@ +# XmlGraphicsBatik + +# Introduction + +The XmlGraphicsBatik project is used to process images in the Scalable Vector Graphics (SVG) format. You can use XmlGraphicsBatik to perform the following operations: + +- Display static and dynamic SVG images. + +- Generate SVG images. + +- Modify the color, style, and content of a SVG image. + +- Parse the XML text of an SVG image into an operable object. + + +# How to Install + +``` +ohpm install @ohos/xmlgraphicsbatik +``` +For details about the OpenHarmony ohpm environment configuration, see [OpenHarmony HAR](https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_har_usage.en.md). + + +# How to Use +The **SVGManager** class is used to generate, operate, and parse SVG images. +> **NOTE** +> +> Before using this library, you need to set the file path in **MainAbility.ts** as follows: +> +> **GlobalContext.getContext().setObject("filesDir", this.context.filesDir);** + +``` +import {SVGManager} from '@ohos/XmlGraphicsBatik'; + +private svgManager: SVGManager = SVGManager.getInstance(); +``` + +## Displaying a SVG Image +``` +// The Image component supports display of media resource files and SVG image in the project directory. +Image($r('app.media.svgSample')) + .width(150) + .height(150) + +Image('file://' + this.filePath + '/svg.svg') + .width(150) + .height(150) +``` + +## Generating an SVG Image File +1. Create an SVG object and elements. + +``` +// Create an SVG object, including declarations and SVG elements. +this.svgManager.createSVGDeclares(); + +// Obtain the root element of the SVG object. +let svgTagObj = this.svgManager.getSVGRoot(); + +// Construct the rect node in the SVG object. +let rect: SVGRect = new SVGRect(); +rect.setX(50); +rect.setY(50); +rect.setRX(20); +rect.setRY(20); +rect.setWidth(100); +rect.setHeight(100); +rect.addAttribute('style', 'fill:rgb(255,0,255);stroke-width:2;stroke:rgb(0,0,0)') + +// Output a rect object in standard format. +let rectObj = rect.toObj(); + +// Construct a node description object in a fixed format. +let svgFormatForRect: SVGSpecifiedFormat = new SVGSpecifiedFormat(); +svgFormatForRect.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT); +svgFormatForRect.setElementName('rect'); +svgFormatForRect.setAttributes(rectObj); + +if (svgTagObj) { + + // Add the Rect element in a fixed format to the SVG object. + this.svgManager.addChildNode(svgTagObj, svgFormatForRect.toObj()); + consoleInfo('Test svg: add svg svgTotalRoot', JSON.stringify(this.svgManager.getSVGTotalObj())); +} + +// Obtain an object corresponding to the entire SVG file. +let svgTotalObj = this.svgManager.getSVGTotalObj(); +let success = function () { + consoleInfo('saveFile', 'success'); +} + +// Save the SVG object as an .svg file in the /project's path/files directory. +this.svgManager.saveSVG('svg.svg', svgTotalObj, success); +``` + +**Result** + +add svg svgTotalRoot: {"declaration":{"attributes":{"version":"1.0","encoding":"utf-8","standalone":"yes"}},"elements":[{"type":"element","name":"svg","attributes":{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},"elements":[{"type":"element","name":"rect","attributes":{"x":50,"y":50,"rx":20,"ry":20,"width":100,"height":100,"style":"fill:rgb(255,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]} + +2. Create an SVG file and elements. + +``` +// Clear the existing SVG root. +this.svgXMLRoot = this.svgManager.getSVGTotalObj(); +this.svgManager.removeByKey(this.svgXMLRoot, SVGAttrConstants.ATTR_KEY_DECLARATION); +this.svgManager.removeByKey(this.svgXMLRoot, SVGAttrConstants.ATTR_KEY_ELEMENTS); + +// Create an SVG object. +let svg: SVGRoot = new SVGRoot(); +svg.setXMLNS(XMLConstants.XMLNS_NAMESPACE_URI_SVG); +svg.setXMLNSLink(XMLConstants.XLINK_NAMESPACE_URI); +svg.setSvgId('svgRoot'); +svg.setXMLSpace(false); +svg.setWidth(250); +svg.setHeight(250); +svg.setViewBox(10, 10, 250, 250); +let svgObj = svg.toObj(); + +let svgSpecifiedFormat: SVGSpecifiedFormat = new SVGSpecifiedFormat(); +svgSpecifiedFormat.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT); +svgSpecifiedFormat.setElementName('svg'); +svgSpecifiedFormat.setAttributes(svgObj); + +// Create a Rect object of the SVG object. +let rect: SVGRect = new SVGRect(); +rect.setX(50); +rect.setY(50); +rect.setRX(20); +rect.setRY(20); +rect.setWidth(100); +rect.setHeight(100); +rect.addAttribute('style', 'fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)') +let rectObj = rect.toObj(); + +let svgFormatForRect: SVGSpecifiedFormat = new SVGSpecifiedFormat(); +svgFormatForRect.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT); +svgFormatForRect.setElementName('rect'); +svgFormatForRect.setAttributes(rectObj); +svgSpecifiedFormat.setElements(svgFormatForRect.toObj()); + +if (this.svgXMLRoot) { + + // Build the SVG file declaration. + let declarationAttrs: object = {}; + declarationAttrs['version'] = '1.0'; + declarationAttrs['encoding'] = 'utf-8'; + declarationAttrs['standalone'] = 'no'; + + let declarationObj: object = {}; + declarationObj[SVGAttrConstants.ATTR_KEY_ATTRIBUTES] = declarationAttrs + + this.svgXMLRoot[SVGAttrConstants.ATTR_KEY_DECLARATION] = declarationObj; + this.svgManager.addChildNode(this.svgXMLRoot, svgSpecifiedFormat.toObj()); + consoleInfo('Test svg: add line svgTotalRoot', JSON.stringify(this.svgManager.getSVGTotalObj())); +} +``` + +Result + +Test svg: add svg svgTotalRoot: {"declaration":{"attributes":{"version":"1.0","encoding":"utf-8","standalone":"no"}},"elements":[{"type":"element","name":"svg","attributes":{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","id":"svgRoot","xml:space":"default","width":250,"height":250,"viewBox":{"x":10,"y":10,"width":250,"height":250}},"elements":[{"type":"element","name":"rect","attributes":{"x":50,"y":50,"rx":20,"ry":20,"width":100,"height":100,"style":"fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]} + +## Operating an SVG Image Object +1. Modify existing attributes of an SVG object. + +``` +// Obtain the root element of the SVG object. +let svgRoot = this.svgManager.getSVGRoot(); +if (!svgRoot) { + consoleInfo('Test rect: update attr for rect1', 'svg tag is null'); + return false; +} + +// Obtain the attribute value based on the key. +let svgElements = this.svgManager.getValueForKey(svgRoot, SVGAttrConstants.ATTR_KEY_ELEMENTS); +if (!svgElements) { + consoleInfo('Test rect: update attr for rect1', `svg tag's elements is null`); + return false; +} + +if (typeof svgElements !== SVGAttrConstants.TYPEOF_OBJECT || !Array.isArray(svgElements)) { + consoleInfo('Test rect: update attr for rect1', `the elements's type of svg tag is not array`); + return; +} + +let rectResult = null; +try { + svgElements.forEach((item) => { + if (typeof item === SVGAttrConstants.TYPEOF_OBJECT) { + let nameValue: string = this.svgManager.getValueForKey(item, SVGAttrConstants.ATTR_KEY_NAME); + if (nameValue === 'rect') { + rectResult = item; + throw 'has got rect,jump out'; + } + } + }) +} catch (e) { + if (!rectResult) { + consoleInfo('Test rect: update attr for rect1', 'rect not exist'); + return; + } + + if (typeof rectResult === SVGAttrConstants.TYPEOF_OBJECT) { + let rectAttributes = rectResult[SVGAttrConstants.ATTR_KEY_ATTRIBUTES]; + rectAttributes['x'] = 20; + rectAttributes['y'] = 20; + rectAttributes['rx'] = 10; + rectAttributes['ry'] = 50; + rectAttributes['width'] = 80; + rectAttributes['height'] = 80; + + // Add or set an attribute in the form of a KV pair for the element. + this.svgManager.setAttribute(rectAttributes, 'style', 'fill:rgb(0,255,0);stroke-width:10;stroke:rgb(0,255,255)'); + this.allAttrRectObj = rectResult; + } + consoleInfo('Test rect: update attr for rect1 svgTotalObj', JSON.stringify(this.svgManager.getSVGTotalObj())); +} +``` + +2. Remove an attribute. + +``` +let attrs = this.svgManager.getValueForKey(rectOriginData, SVGAttrConstants.ATTR_KEY_ATTRIBUTES); +if (!attrs) { + consoleInfo('test remove ' + firstAttrName, 'rect1 has no attributes'); + return; +} +this.svgManager.removeByKey(attrs, firstAttrName); +``` + +## Parsing an SVG Image File +``` +this.svgManager.parse('svg.svg', (parseXMLResultObj) =>{ + this.svgJson = parseXMLResultObj; +}) +``` + +**Result** + +{"declaration":{"attributes":{"version":"1.0","encoding":"utf-8"}},"elements":[{"type":"element","name":"svg","attributes":{"id":"svgRoot","space":"default","width":"250","height":"250","viewBox":"10 10 250 250 "},"elements":[{"type":"element","name":"rect","attributes":{"x":"50","y":"50","rx":"20","ry":"20","width":"100","height":"100","style":"fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]} + +# Available APIs + +| API | Description | +| ------------------------------------------------------------ | -------------------------------------- | +| static getInstance(): SVGManager | Obtains an **SVGManager** instance. | +| getSVGTotalObj(): object | Obtains an operable object corresponding to an entire SVG file. | +| createSVGDeclares(): object | Creates SVG declarations. | +| getSVGRoot(obj: Object = this.svgObj): object | Obtains the root element of an SVG object. | +| addChildNode(parentObj: Object, childPropertyValue: Object): boolean | Adds a child node. This operation will not overwrite the atomic tag. | +| setChildNode(parentObj: Object, childPropertyValue: Object): boolean | Sets a child node. This operation overwrites the atomic tag. | +| getValueForKey(parentObj: Object, key: string): any | Obtains the value of the given key. | +| removeByKey(parentObj: Object, key: string): void | Removes a key-value (KV) pair based on the given key. | +| setAttribute(parentObj: Object, key: string, value: string): void | Sets an attribute or child node for an object. The KV pair set overwrites the original one.| +| createFolder(path: string): void | Creates a folder. | +| getFilePath(onSuccess: (filesDir: string) => void): void | Obtains the root path of a file. | +| saveSVG(fileName: string, fileContent: string \| Object, onSuccess?: () => void, onFailed?: (number, Error) => void): void | Saves an SVG file. | +| parse(fileName: string, onSuccess: (result: string) => void, onFailed?: (error: Error) => void): void | Parses an SVG file. | + + +# Constraints + +This project has been verified in the following versions: + +- DevEco Studio: 4.1 Canary(4.1.3.322), SDK: API11 (4.1.0.36) + +- DevEco Studio: 4.0 (4.0.3.600), SDK: API10 (4.0.10.11) + +- DevEco Studio: 4.0 (4.0.3.512), SDK: API10 (4.0.10.9) + +- DevEco Studio: 3.1 Beta2(3.1.0.400), SDK: API9 Release(3.2.11.9) + + +# Directory Structure +``` +/XmlGraphicsBatik # Root directory of the project. +├── entry # Sample code. +├── library # Source code of the third-party library. +│ └── src +│ ├── index.ets # File exposed externally. +│ ├── package.json # Project introduction. +│ └──main/ets/batik +│ ├── SVGManager.ets # SVGManager class. +│ ├── SVGXMLChecker.ets # Used to check whether the SVG files adhere to SVG specifications. +│ ├── StringReader.ets # Used to read SVG strings. +│ └── constants +│ ├── RegexConstants.ets # Constants for regular expressions. +│ ├── SVGAttrConstants.ets # Constants for SVG keys in standard format. +│ ├── SVGXMLConstants.ets # Constants for SVG files. +│ └── XMLConstants.ets # Constants for XML files. +│ └── svggen +│ ├── SVGSpecifiedFormat.ets # Defines the formats specific to SVG files (defining how SVG elements are structured or formatted). +│ ├── SVGDeclares.ets # Provides SVG-related declarations. +│ ├── SVGRoot.ets # Defines how to handle the SVG file root element, which is the top-level container for all SVG elements. +│ ├── SVGCircle.ets # Defines how to handle SVG circle elements. +│ ├── SVGEllipse.ets # Defines how to handle SVG ellipse elements. +│ ├── SVGLine.ets # Defines how to handle SVG line elements. +│ ├── SVGPath.ets # Defines how to handle SVG path elements. +│ ├── SVGRect.ets # Defines how to handle SVG rectangle elements. +│ └── SVGPolygonAndPolyLine.ets # Defines how to handle SVG polygon and polyline elements. +│ └── tools +│ ├── DeleteProperty.ts # Provides a function for deleting a property. +│ ├── GetKeysTest.ts # Provides a function for obtaining keys. +│ ├── GlobalContext.ets # Defines a global context. +│ ├── IsArrayFunction.ts # Provides a function for checking whether the given value is an array. +│ ├── MakePropertiesImmutable.ts # Provides a function for making the properties of an object unchangeable. +│ ├── ObjCreate.ts # Provides a function for creating an empty object. +│ └── StringToHex.ts # Provides a function for converting strings into hexadecimal formats. +│ └── util +│ ├── LogUtil.ets # Utility for logging. +│ ├── ObjOrArrayUtil.ets # Utility for processing operable objects and arrays. +│ └── XMLRules.ets # File containing rules or validation logic related to XML. +``` + +# How to Contribute +If you find any problem during the use, submit an [Issue](https://gitee.com/openharmony-tpc/XmlGraphicsBatik/issues) or a [PR](https://gitee.com/openharmony-tpc/XmlGraphicsBatik/pulls). + + + +# License +This project is licensed under the terms of the [Apache License 2.0](https://gitee.com/openharmony-tpc/XmlGraphicsBatik/blob/master/LICENSE). -- Gitee