/src/scenegraph/svg_attributes.c
C | 6443 lines | 5960 code | 325 blank | 158 comment | 1469 complexity | a2132d966357a269fa240b28914370a7 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- * GPAC Multimedia Framework
- *
- * Authors: Cyril Concolato - Jean le Feuvre - Jean-Claude Moissinac
- * Copyright (c) 2005-200X ENST
- * All rights reserved
- *
- * This file is part of GPAC / SVG Loader module
- *
- * GPAC is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * GPAC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
- #include <gpac/base_coding.h>
- #include <gpac/events.h>
- #include <gpac/nodes_svg.h>
- #ifndef GPAC_DISABLE_SVG
- #include <gpac/internal/scenegraph_dev.h>
- #define DUMP_COORDINATES 1
- static const struct dom_event_def {u32 event; const char *name; u32 category; } defined_dom_events [] =
- {
- { GF_EVENT_ABORT, "abort", GF_DOM_EVENT_DOM },
- { GF_EVENT_ERROR, "error", GF_DOM_EVENT_DOM },
- { GF_EVENT_LOAD, "load", GF_DOM_EVENT_DOM },
- { GF_EVENT_UNLOAD, "unload", GF_DOM_EVENT_DOM },
- /*focus - we differentiate from UI/key events to avoid browing focus if no listener is on place*/
- { GF_EVENT_FOCUSIN, "DOMFocusIn", GF_DOM_EVENT_FOCUS },
- { GF_EVENT_FOCUSIN, "focusin", GF_DOM_EVENT_FOCUS },
- { GF_EVENT_FOCUSOUT, "DOMFocusOut", GF_DOM_EVENT_FOCUS },
- { GF_EVENT_FOCUSOUT, "focusout", GF_DOM_EVENT_FOCUS },
- { GF_EVENT_CHANGE, "change", GF_DOM_EVENT_FOCUS },
- { GF_EVENT_FOCUS, "focus", GF_DOM_EVENT_FOCUS },
- { GF_EVENT_BLUR, "blur", GF_DOM_EVENT_FOCUS },
- /*key events*/
- { GF_EVENT_KEYDOWN, "keydown", GF_DOM_EVENT_KEY },
- { GF_EVENT_KEYDOWN, "accesskey", GF_DOM_EVENT_KEY },
- { GF_EVENT_KEYDOWN, "keypress", GF_DOM_EVENT_KEY },
- { GF_EVENT_KEYUP, "keyup", GF_DOM_EVENT_KEY },
- { GF_EVENT_LONGKEYPRESS, "longaccesskey", GF_DOM_EVENT_KEY },
- { GF_EVENT_CLICK, "click", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_DBLCLICK, "dblclick", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_MOUSEDOWN, "mousedown", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_MOUSEMOVE, "mousemove", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_MOUSEOUT, "mouseout", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_MOUSEOVER, "mouseover", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_MOUSEUP, "mouseup", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_MOUSEWHEEL, "wheel", GF_DOM_EVENT_MOUSE },
- { GF_EVENT_MOUSEWHEEL, "SVGMousewheel", GF_DOM_EVENT_MOUSE },
- /*activate is not a basic DOM but a MOUSE and KEY event*/
- { GF_EVENT_ACTIVATE, "activate", GF_DOM_EVENT_MOUSE | GF_DOM_EVENT_KEY },
- { GF_EVENT_ACTIVATE, "DOMActivate", GF_DOM_EVENT_MOUSE | GF_DOM_EVENT_KEY },
- /*text events*/
- { GF_EVENT_TEXTINPUT, "textInput", GF_DOM_EVENT_TEXT },
- { GF_EVENT_TEXTSELECT, "select", GF_DOM_EVENT_TEXT },
- /*SMIL events*/
- { GF_EVENT_BEGIN, "begin", GF_DOM_EVENT_FAKE },
- { GF_EVENT_BEGIN_EVENT, "beginEvent", GF_DOM_EVENT_SMIL },
- { GF_EVENT_END, "end", GF_DOM_EVENT_FAKE },
- { GF_EVENT_END_EVENT, "endEvent", GF_DOM_EVENT_SMIL },
- { GF_EVENT_REPEAT, "repeat", GF_DOM_EVENT_FAKE },
- { GF_EVENT_REPEAT_EVENT, "repeatEvent", GF_DOM_EVENT_SMIL },
- /*all SVG/HTML/... UI events*/
- { GF_EVENT_RESIZE, "resize", GF_DOM_EVENT_UI },
- { GF_EVENT_SCROLL, "scroll", GF_DOM_EVENT_UI },
- { GF_EVENT_ZOOM, "zoom", GF_DOM_EVENT_UI },
- { GF_EVENT_LOAD, "SVGLoad", GF_DOM_EVENT_DOM },
- { GF_EVENT_RESIZE, "SVGResize", GF_DOM_EVENT_UI },
- { GF_EVENT_SCROLL, "SVGScroll", GF_DOM_EVENT_UI },
- { GF_EVENT_ZOOM, "SVGZoom", GF_DOM_EVENT_UI },
- /*mutation events and DCCI*/
- { GF_EVENT_TREE_MODIFIED, "DOMSubtreeModified", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_NODE_INSERTED, "DOMNodeInserted", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_NODE_REMOVED, "DOMNodeRemoved", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_NODE_REMOVED_DOC, "DOMNodeRemovedFromDocument", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_NODE_INSERTED_DOC, "DOMNodeInsertedIntoDocument", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_ATTR_MODIFIED, "DOMAttrModified", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_CHAR_DATA_MODIFIED, "DOMCharacterDataModified", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_NODE_NAME_CHANGED, "DOMElementNameChanged", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_ATTR_NAME_CHANGED, "DOMAttributeNameChanged", GF_DOM_EVENT_MUTATION },
- { GF_EVENT_DCCI_PROP_CHANGE, "DCCI-prop-change", GF_DOM_EVENT_MUTATION },
- /*LASeR events - some events are attached to other categorues*/
- { GF_EVENT_ACTIVATED, "activatedEvent", GF_DOM_EVENT_LASER },
- { GF_EVENT_DEACTIVATED, "deactivatedEvent", GF_DOM_EVENT_LASER },
- { GF_EVENT_EXECUTION_TIME, "executionTime", GF_DOM_EVENT_FAKE },
- { GF_EVENT_PAUSE, "pause", GF_DOM_EVENT_SMIL },
- { GF_EVENT_PAUSED_EVENT, "pausedEvent", GF_DOM_EVENT_SMIL },
- { GF_EVENT_PLAY, "play", GF_DOM_EVENT_SMIL },
- { GF_EVENT_RESUME_EVENT, "resumedEvent", GF_DOM_EVENT_SMIL },
- { GF_EVENT_REPEAT_KEY, "repeatKey", GF_DOM_EVENT_KEY },
- { GF_EVENT_SHORT_ACCESSKEY, "shortAccessKey", GF_DOM_EVENT_KEY },
- /*LASeR unofficial events*/
- { GF_EVENT_BATTERY, "battery", GF_DOM_EVENT_LASER },
- { GF_EVENT_CPU, "cpu", GF_DOM_EVENT_LASER },
- /*MediaAccess events*/
- #if 0
- { GF_EVENT_MEDIA_BEGIN_SESSION_SETUP, "BeginSessionSetup", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_END_SESSION_SETUP, "EndSessionSetup", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_DATA_REQUEST, "DataRequest", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_PLAYABLE, "Playable", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_NOT_PLAYABLE, "NotPlayable", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_DATA_PROGRESS, "DataReceptionProgress", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_END_OF_DATA, "EndOfDataReception", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_STOP, "Stop", GF_DOM_EVENT_MEDIA_ACCESS },
- { GF_EVENT_MEDIA_ERROR, "Error", GF_DOM_EVENT_MEDIA_ACCESS },
- #endif
- { GF_EVENT_MEDIA_SETUP_BEGIN, "setupbegin", GF_DOM_EVENT_MEDIA},
- { GF_EVENT_MEDIA_SETUP_DONE, "setupdone", GF_DOM_EVENT_MEDIA},
- { GF_EVENT_MEDIA_LOAD_START, "loadstart", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_LOAD_DONE, "loaddone", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_PROGRESS, "progress", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_SUSPEND, "suspend", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_ABORT, "abort", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_ERROR, "error", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_EMPTIED, "emptied", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_STALLED, "stalled", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_LOADED_METADATA, "loadedmetadata", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_LODADED_DATA, "loadeddata", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_CANPLAY, "canplay", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_CANPLAYTHROUGH, "canplaythrough", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_PLAYING, "playing", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_WAITING, "waiting", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_SEEKING, "seeking", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_SEEKED, "seeked", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_ENDED, "ended", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_DURATION_CHANGED, "durationchanged", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_TIME_UPDATE, "timeupdate", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_PLAY, "play", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_PAUSE, "pause", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_RATECHANGE, "ratechange", GF_DOM_EVENT_MEDIA },
- { GF_EVENT_MEDIA_VOLUME_CHANGED, "volumechange", GF_DOM_EVENT_MEDIA },
- /*GPAC internals*/
- { GF_EVENT_SCENE_ATTACHED, "gpac_scene_attached", GF_DOM_EVENT_DOM },
- { GF_EVENT_VP_RESIZE, "gpac_vp_changed", GF_DOM_EVENT_DOM },
- };
- GF_EXPORT
- u32 gf_dom_event_type_by_name(const char *name)
- {
- u32 i, count;
- count = sizeof(defined_dom_events) / sizeof(struct dom_event_def);
- if (!name) return GF_EVENT_UNKNOWN;
- if ((name[0]=='o') && (name[1]=='n')) name += 2;
- for (i=0;i<count;i++) {
- if (!strcmp(name, defined_dom_events[i].name))
- return defined_dom_events[i].event;
- }
- return GF_EVENT_UNKNOWN;
- }
- const char *gf_dom_event_get_name(u32 type)
- {
- u32 i, count;
- count = sizeof(defined_dom_events) / sizeof(struct dom_event_def);
- for (i=0;i<count;i++) {
- if (defined_dom_events[i].event == type)
- return defined_dom_events[i].name;
- }
- return "unknown";
- }
- u32 gf_dom_event_get_category(u32 type)
- {
- u32 i, count;
- count = sizeof(defined_dom_events) / sizeof(struct dom_event_def);
- for (i=0;i<count;i++) {
- if (defined_dom_events[i].event == type)
- return defined_dom_events[i].category;
- }
- return 0;
- }
- static const struct predef_keyid {u32 key_code; const char *name; } predefined_key_identifiers[] =
- {
- { GF_KEY_ACCEPT, "Accept" },
- { GF_KEY_AGAIN, "Again" },
- { GF_KEY_ALLCANDIDATES, "AllCandidates" },
- { GF_KEY_ALPHANUM, "Alphanumeric" },
- { GF_KEY_ALT, "Alt" },
- { GF_KEY_ALTGRAPH, "AltGraph" },
- { GF_KEY_APPS, "Apps" },
- { GF_KEY_ATTN, "Attn" },
- { GF_KEY_BROWSERBACK, "BrowserBack" },
- { GF_KEY_BROWSERFAVORITES, "BrowserFavorites" },
- { GF_KEY_BROWSERFORWARD, "BrowserForward" },
- { GF_KEY_BROWSERHOME, "BrowserHome" },
- { GF_KEY_BROWSERREFRESH, "BrowserRefresh" },
- { GF_KEY_BROWSERSEARCH, "BrowserSearch" },
- { GF_KEY_BROWSERSTOP, "BrowserStop" },
- { GF_KEY_CAPSLOCK, "CapsLock" },
- { GF_KEY_CLEAR, "Clear" },
- { GF_KEY_CODEINPUT, "CodeInput" },
- { GF_KEY_COMPOSE, "Compose" },
- { GF_KEY_CONTROL, "Control" },
- { GF_KEY_CRSEL, "Crsel" },
- { GF_KEY_CONVERT, "Convert" },
- { GF_KEY_COPY, "Copy" },
- { GF_KEY_CUT, "Cut" },
- { GF_KEY_DOWN, "Down" },
- { GF_KEY_END, "End" },
- { GF_KEY_ENTER, "Enter" },
- { GF_KEY_ERASEEOF, "EraseEof" },
- { GF_KEY_EXECUTE, "Execute" },
- { GF_KEY_EXSEL, "Exsel" },
- { GF_KEY_F1, "F1" },
- { GF_KEY_F2, "F2" },
- { GF_KEY_F3, "F3" },
- { GF_KEY_F4, "F4" },
- { GF_KEY_F5, "F5" },
- { GF_KEY_F6, "F6" },
- { GF_KEY_F7, "F7" },
- { GF_KEY_F8, "F8" },
- { GF_KEY_F9, "F9" },
- { GF_KEY_F10, "F10" },
- { GF_KEY_F11, "F11" },
- { GF_KEY_F12, "F12" },
- { GF_KEY_F13, "F13" },
- { GF_KEY_F14, "F14" },
- { GF_KEY_F15, "F15" },
- { GF_KEY_F16, "F16" },
- { GF_KEY_F17, "F17" },
- { GF_KEY_F18, "F18" },
- { GF_KEY_F19, "F19" },
- { GF_KEY_F20, "F20" },
- { GF_KEY_F21, "F21" },
- { GF_KEY_F22, "F22" },
- { GF_KEY_F23, "F23" },
- { GF_KEY_F24, "F24" },
- { GF_KEY_FINALMODE, "FinalMode" },
- { GF_KEY_FIND, "Find" },
- { GF_KEY_FULLWIDTH, "FullWidth" },
- { GF_KEY_HALFWIDTH, "HalfWidth" },
- { GF_KEY_HANGULMODE, "HangulMode" },
- { GF_KEY_HANJAMODE, "HanjaMode" },
- { GF_KEY_HELP, "Help" },
- { GF_KEY_HIRAGANA, "Hiragana" },
- { GF_KEY_HOME, "Home" },
- { GF_KEY_INSERT, "Insert" },
- { GF_KEY_JAPANESEHIRAGANA, "JapaneseHiragana" },
- { GF_KEY_JAPANESEKATAKANA, "JapaneseKatakana" },
- { GF_KEY_JAPANESEROMAJI, "JapaneseRomaji" },
- { GF_KEY_JUNJAMODE, "JunjaMode" },
- { GF_KEY_KANAMODE, "KanaMode" },
- { GF_KEY_KANJIMODE, "KanjiMode" },
- { GF_KEY_KATAKANA, "Katakana" },
- { GF_KEY_LAUNCHAPPLICATION1, "LaunchApplication1" },
- { GF_KEY_LAUNCHAPPLICATION2, "LaunchApplication2" },
- { GF_KEY_LAUNCHMAIL, "LaunchMail" },
- { GF_KEY_LEFT, "Left" },
- { GF_KEY_META, "Meta" },
- { GF_KEY_MEDIANEXTTRACK, "MediaNextTrack" },
- { GF_KEY_MEDIAPLAYPAUSE, "MediaPlayPause" },
- { GF_KEY_MEDIAPREVIOUSTRACK, "MediaPreviousTrack" },
- { GF_KEY_MEDIASTOP, "MediaStop" },
- { GF_KEY_MODECHANGE, "ModeChange" },
- { GF_KEY_NONCONVERT, "Nonconvert" },
- { GF_KEY_NUMLOCK, "NumLock" },
- { GF_KEY_PAGEDOWN, "PageDown" },
- { GF_KEY_PAGEUP, "PageUp" },
- { GF_KEY_PASTE, "Paste" },
- { GF_KEY_PAUSE, "Pause" },
- { GF_KEY_PLAY, "Play" },
- { GF_KEY_PREVIOUSCANDIDATE, "PreviousCandidate" },
- { GF_KEY_PRINTSCREEN, "PrintScreen" },
- { GF_KEY_PROCESS, "Process" },
- { GF_KEY_PROPS, "Props" },
- { GF_KEY_RIGHT, "Right" },
- { GF_KEY_ROMANCHARACTERS, "RomanCharacters" },
- { GF_KEY_SCROLL, "Scroll" },
- { GF_KEY_SELECT, "Select" },
- { GF_KEY_SELECTMEDIA, "SelectMedia" },
- { GF_KEY_SHIFT, "Shift" },
- { GF_KEY_STOP, "Stop" },
- { GF_KEY_UP, "Up" },
- { GF_KEY_UNDO, "Undo" },
- { GF_KEY_VOLUMEDOWN, "VolumeDown" },
- { GF_KEY_VOLUMEMUTE, "VolumeMute" },
- { GF_KEY_VOLUMEUP, "VolumeUp" },
- { GF_KEY_WIN, "Win" },
- { GF_KEY_ZOOM, "Zoom" },
- { GF_KEY_BACKSPACE, "U+0008" },
- { GF_KEY_TAB, "U+0009" },
- { GF_KEY_CANCEL, "U+0018" },
- { GF_KEY_ESCAPE, "U+001B" },
- { GF_KEY_SPACE, "U+0020" },
- { GF_KEY_EXCLAMATION, "U+0021" },
- { GF_KEY_QUOTATION, "U+0022" },
- { GF_KEY_NUMBER, "U+0023" },
- { GF_KEY_DOLLAR, "U+0024" },
- { GF_KEY_AMPERSAND, "U+0026" },
- { GF_KEY_APOSTROPHE, "U+0027" },
- { GF_KEY_LEFTPARENTHESIS, "U+0028" },
- { GF_KEY_RIGHTPARENTHESIS, "U+0029" },
- { GF_KEY_STAR, "U+002A" },
- { GF_KEY_PLUS, "U+002B" },
- { GF_KEY_COMMA, "U+002C" },
- { GF_KEY_HYPHEN, "U+002D" },
- { GF_KEY_FULLSTOP, "U+002E" },
- { GF_KEY_SLASH, "U+002F" },
- { GF_KEY_0, "U+0030" },
- { GF_KEY_1, "U+0031" },
- { GF_KEY_2, "U+0032" },
- { GF_KEY_3, "U+0033" },
- { GF_KEY_4, "U+0034" },
- { GF_KEY_5, "U+0035" },
- { GF_KEY_6, "U+0036" },
- { GF_KEY_7, "U+0037" },
- { GF_KEY_8, "U+0038" },
- { GF_KEY_9, "U+0039" },
- { GF_KEY_COLON, "U+003A" },
- { GF_KEY_SEMICOLON, "U+003B" },
- { GF_KEY_LESSTHAN, "U+003C" },
- { GF_KEY_EQUALS, "U+003D" },
- { GF_KEY_GREATERTHAN, "U+003E" },
- { GF_KEY_QUESTION, "U+003F" },
- { GF_KEY_AT, "U+0040" },
- { GF_KEY_A, "U+0041" },
- { GF_KEY_B, "U+0042" },
- { GF_KEY_C, "U+0043" },
- { GF_KEY_D, "U+0044" },
- { GF_KEY_E, "U+0045" },
- { GF_KEY_F, "U+0046" },
- { GF_KEY_G, "U+0047" },
- { GF_KEY_H, "U+0048" },
- { GF_KEY_I, "U+0049" },
- { GF_KEY_J, "U+004A" },
- { GF_KEY_K, "U+004B" },
- { GF_KEY_L, "U+004C" },
- { GF_KEY_M, "U+004D" },
- { GF_KEY_N, "U+004E" },
- { GF_KEY_O, "U+004F" },
- { GF_KEY_P, "U+0050" },
- { GF_KEY_Q, "U+0051" },
- { GF_KEY_R, "U+0052" },
- { GF_KEY_S, "U+0053" },
- { GF_KEY_T, "U+0054" },
- { GF_KEY_U, "U+0055" },
- { GF_KEY_V, "U+0056" },
- { GF_KEY_W, "U+0057" },
- { GF_KEY_X, "U+0058" },
- { GF_KEY_Y, "U+0059" },
- { GF_KEY_Z, "U+005A" },
- { GF_KEY_LEFTSQUAREBRACKET, "U+005B" },
- { GF_KEY_BACKSLASH, "U+005C" },
- { GF_KEY_RIGHTSQUAREBRACKET, "U+005D" },
- { GF_KEY_CIRCUM, "U+005E" },
- { GF_KEY_UNDERSCORE, "U+005F" },
- { GF_KEY_GRAVEACCENT, "U+0060" },
- { GF_KEY_LEFTCURLYBRACKET, "U+007B" },
- { GF_KEY_PIPE, "U+007C" },
- { GF_KEY_RIGHTCURLYBRACKET, "U+007D" },
- { GF_KEY_DEL, "U+007F" },
- { GF_KEY_INVERTEXCLAMATION, "U+00A1" },
- { GF_KEY_DEADGRAVE, "U+0300" },
- { GF_KEY_DEADEACUTE, "U+0301" },
- { GF_KEY_DEADCIRCUM, "U+0302" },
- { GF_KEY_DEADTILDE, "U+0303" },
- { GF_KEY_DEADMACRON, "U+0304" },
- { GF_KEY_DEADBREVE, "U+0306" },
- { GF_KEY_DEADABOVEDOT, "U+0307" },
- { GF_KEY_DEADDIARESIS, "U+0308" },
- { GF_KEY_DEADRINGABOVE, "U+030A" },
- { GF_KEY_DEADDOUBLEACUTE, "U+030B" },
- { GF_KEY_DEADCARON, "U+030C" },
- { GF_KEY_DEADCEDILLA, "U+0327" },
- { GF_KEY_DEADOGONEK, "U+0328" },
- { GF_KEY_DEADIOTA, "U+0345" },
- { GF_KEY_EURO, "U+20AC" },
- { GF_KEY_DEADVOICESOUND, "U+3099" },
- { GF_KEY_DEADSEMIVOICESOUND, "U+309A" },
- { GF_KEY_CHANNELUP, "ChannelUp" },
- { GF_KEY_CHANNELDOWN, "ChannelDown" },
- { GF_KEY_TEXT, "Text" },
- { GF_KEY_INFO, "Info" },
- { GF_KEY_EPG, "EPG" },
- { GF_KEY_RECORD, "Record" },
- { GF_KEY_BEGINPAGE, "BeginPage" }
- };
- GF_EXPORT
- const char *gf_dom_get_key_name(u32 key_identifier)
- {
- u32 count = sizeof(predefined_key_identifiers) / sizeof(struct predef_keyid);
- if (!key_identifier || count<=key_identifier) return "Unknown";
- return predefined_key_identifiers[key_identifier-1].name;
- }
- u32 gf_dom_get_key_type(char *key_name)
- {
- if (strlen(key_name) == 1) {
- char c[2];
- c[0] = key_name[0];
- c[1] = 0;
- strupr(c);
- if (c[0] >= 'A' && c[0] <= 'Z')
- return (GF_KEY_A + (c[0] - 'A') );
- if (c[0] >= '0' && c[0] <= '9')
- return ( GF_KEY_0 + (c[0] - '0') );
- switch (c[0]) {
- case '@': return GF_KEY_AT;
- case '*': return GF_KEY_STAR;
- case '#': return GF_KEY_NUMBER;
- case ' ': return GF_KEY_SPACE;
- case '!': return GF_KEY_EXCLAMATION;
- case '"': return GF_KEY_QUOTATION;
- case '$': return GF_KEY_DOLLAR;
- case '&': return GF_KEY_AMPERSAND;
- case '\'': return GF_KEY_APOSTROPHE;
- case '(': return GF_KEY_LEFTPARENTHESIS;
- case ')': return GF_KEY_RIGHTPARENTHESIS;
- case '+': return GF_KEY_PLUS;
- case ',': return GF_KEY_COMMA;
- case '-': return GF_KEY_HYPHEN;
- case '.': return GF_KEY_FULLSTOP;
- case '/': return GF_KEY_SLASH;
- case ':': return GF_KEY_COLON;
- case ';': return GF_KEY_SEMICOLON;
- case '<': return GF_KEY_LESSTHAN;
- case '=': return GF_KEY_EQUALS;
- case '>': return GF_KEY_GREATERTHAN;
- case '?': return GF_KEY_QUESTION;
- case '[': return GF_KEY_LEFTSQUAREBRACKET;
- case '\\': return GF_KEY_BACKSLASH;
- case ']': return GF_KEY_RIGHTSQUAREBRACKET;
- case '^': return GF_KEY_CIRCUM;
- case '_': return GF_KEY_UNDERSCORE;
- case '`': return GF_KEY_GRAVEACCENT;
- case '{': return GF_KEY_LEFTCURLYBRACKET;
- case '|': return GF_KEY_PIPE;
- case '}': return GF_KEY_RIGHTCURLYBRACKET;
- case 'Ą': return GF_KEY_INVERTEXCLAMATION;
- default: return GF_KEY_UNIDENTIFIED;
- }
- } else {
- u32 i, count;
- count = sizeof(predefined_key_identifiers) / sizeof(struct predef_keyid);
- for (i=0; i<count; i++) {
- if (!stricmp(key_name, predefined_key_identifiers[i].name)) {
- return predefined_key_identifiers[i].key_code;
- }
- }
- return GF_KEY_UNIDENTIFIED;
- }
- }
- /* Basic SVG datatype parsing functions */
- static const struct predef_col { const char *name; u8 r; u8 g; u8 b; } predefined_colors[] =
- {
- {"aliceblue",240, 248, 255},
- {"antiquewhite",250, 235, 215},
- {"aqua", 0, 255, 255},
- {"aquamarine",127, 255, 212},
- {"azure",240, 255, 255},
- {"beige",245, 245, 220},
- {"bisque",255, 228, 196},
- {"black", 0, 0, 0},
- {"blanchedalmond",255, 235, 205},
- {"blue", 0, 0, 255},
- {"blueviolet",138, 43, 226},
- {"brown",165, 42, 42},
- {"burlywood",222, 184, 135},
- {"cadetblue", 95, 158, 160},
- {"chartreuse",127, 255, 0},
- {"chocolate",210, 105, 30},
- {"coral",255, 127, 80},
- {"lightpink",255, 182, 193},
- {"lightsalmon",255, 160, 122},
- {"lightseagreen", 32, 178, 170},
- {"lightskyblue",135, 206, 250},
- {"lightslategray",119, 136, 153},
- {"lightslategrey",119, 136, 153},
- {"lightsteelblue",176, 196, 222},
- {"lightyellow",255, 255, 224},
- {"lime", 0, 255, 0},
- {"limegreen", 50, 205, 50},
- {"linen",250, 240, 230},
- {"magenta",255, 0, 255},
- {"maroon",128, 0, 0},
- {"mediumaquamarine",102, 205, 170},
- {"mediumblue", 0, 0, 205},
- {"mediumorchid",186, 85, 211},
- {"cornflowerblue",100, 149, 237},
- {"cornsilk",255, 248, 220},
- {"crimson",220, 20, 60},
- {"cyan", 0, 255, 255},
- {"darkblue", 0, 0, 139},
- {"darkcyan", 0, 139, 139},
- {"darkgoldenrod",184, 134, 11},
- {"darkgray",169, 169, 169},
- {"darkgreen", 0, 100, 0},
- {"darkgrey",169, 169, 169},
- {"darkkhaki",189, 183, 107},
- {"darkmagenta",139, 0, 139},
- {"darkolivegreen", 85, 107, 47},
- {"darkorange",255, 140, 0},
- {"darkorchid",153, 50, 204},
- {"darkred",139, 0, 0},
- {"darksalmon",233, 150, 122},
- {"darkseagreen",143, 188, 143},
- {"darkslateblue", 72, 61, 139},
- {"darkslategray", 47, 79, 79},
- {"darkslategrey", 47, 79, 79},
- {"darkturquoise", 0, 206, 209},
- {"darkviolet",148, 0, 211},
- {"deeppink",255, 20, 147},
- {"deepskyblue", 0, 191, 255},
- {"dimgray",105, 105, 105},
- {"dimgrey",105, 105, 105},
- {"dodgerblue", 30, 144, 255},
- {"firebrick",178, 34, 34},
- {"floralwhite",255, 250, 240},
- {"forestgreen", 34, 139, 34},
- {"fuchsia",255, 0, 255},
- {"gainsboro",220, 220, 220},
- {"ghostwhite",248, 248, 255},
- {"gold",255, 215, 0},
- {"goldenrod",218, 165, 32},
- {"gray",128, 128, 128},
- {"grey",128, 128, 128},
- {"green", 0, 128, 0},
- {"greenyellow",173, 255, 47},
- {"honeydew",240, 255, 240},
- {"hotpink",255, 105, 180},
- {"indianred",205, 92, 92},
- {"indigo", 75, 0, 130},
- {"ivory",255, 255, 240},
- {"khaki",240, 230, 140},
- {"lavender",230, 230, 25},
- {"lavenderblush",255, 240, 245},
- {"mediumpurple",147, 112, 219},
- {"mediumseagreen", 60, 179, 113},
- {"mediumslateblue",123, 104, 238},
- {"mediumspringgreen", 0, 250, 154},
- {"mediumturquoise", 72, 209, 204},
- {"mediumvioletred",199, 21, 133},
- {"midnightblue", 25, 25, 112},
- {"mintcream",245, 255, 250},
- {"mistyrose",255, 228, 225},
- {"moccasin",255, 228, 181},
- {"navajowhite",255, 222, 173},
- {"navy", 0, 0, 128},
- {"oldlace",253, 245, 230},
- {"olive",128, 128, 0},
- {"olivedrab",107, 142, 35},
- {"orange",255, 165, 0},
- {"orangered",255, 69, 0},
- {"orchid",218, 112, 214},
- {"palegoldenrod",238, 232, 170},
- {"palegreen",152, 251, 152},
- {"paleturquoise",175, 238, 238},
- {"palevioletred",219, 112, 147},
- {"papayawhip",255, 239, 213},
- {"peachpuff",255, 218, 185},
- {"peru",205, 133, 63},
- {"pink",255, 192, 203},
- {"plum",221, 160, 221},
- {"powderblue",176, 224, 230},
- {"purple",128, 0, 128},
- {"red",255, 0, 0},
- {"rosybrown",188, 143, 143},
- {"royalblue", 65, 105, 225},
- {"saddlebrown",139, 69, 19},
- {"salmon",250, 128, 114},
- {"sandybrown",244, 164, 96},
- {"seagreen", 46, 139, 87},
- {"seashell",255, 245, 238},
- {"sienna",160, 82, 45},
- {"silver",192, 192, 192},
- {"skyblue",135, 206, 235},
- {"slateblue",106, 90, 205},
- {"slategray",112, 128, 144},
- {"slategrey",112, 128, 144},
- {"snow",255, 250, 250},
- {"springgreen", 0, 255, 127},
- {"steelblue", 70, 130, 180},
- {"tan",210, 180, 140},
- {"teal", 0, 128, 128},
- {"lawngreen",124, 252, 0},
- {"lemonchiffon",255, 250, 205},
- {"lightblue",173, 216, 230},
- {"lightcoral",240, 128, 128},
- {"lightcyan",224, 255, 255},
- {"lightgoldenrodyellow",250, 250, 210},
- {"lightgray",211, 211, 211},
- {"lightgreen",144, 238, 144},
- {"lightgrey",211, 211, 211},
- {"thistle",216, 191, 216},
- {"tomato",255, 99, 71},
- {"turquoise", 64, 224, 208},
- {"violet",238, 130, 238},
- {"wheat",245, 222, 179},
- {"white",255, 255, 255},
- {"whitesmoke",245, 245, 245},
- {"yellow",255, 255, 0},
- {"yellowgreen",154, 205, 50}
- };
- /* Basic SVG datatype parsing functions */
- static const struct sys_col { const char *name; u8 type; } system_colors[] =
- {
- {"ActiveBorder", SVG_COLOR_ACTIVE_BORDER},
- {"ActiveCaption", SVG_COLOR_ACTIVE_CAPTION},
- {"AppWorkspace", SVG_COLOR_APP_WORKSPACE},
- {"Background", SVG_COLOR_BACKGROUND},
- {"ButtonFace", SVG_COLOR_BUTTON_FACE},
- {"ButtonHighlight", SVG_COLOR_BUTTON_HIGHLIGHT},
- {"ButtonShadow", SVG_COLOR_BUTTON_SHADOW},
- {"ButtonText", SVG_COLOR_BUTTON_TEXT},
- {"CaptionText", SVG_COLOR_CAPTION_TEXT},
- {"GrayText", SVG_COLOR_GRAY_TEXT},
- {"Highlight", SVG_COLOR_HIGHLIGHT},
- {"HighlightText", SVG_COLOR_HIGHLIGHT_TEXT},
- {"InactiveBorder", SVG_COLOR_INACTIVE_BORDER},
- {"InactiveCaption", SVG_COLOR_INACTIVE_CAPTION},
- {"InactiveCaptionText", SVG_COLOR_INACTIVE_CAPTION_TEXT},
- {"InfoBackground", SVG_COLOR_INFO_BACKGROUND},
- {"InfoText", SVG_COLOR_INFO_TEXT},
- {"Menu", SVG_COLOR_MENU},
- {"MenuText", SVG_COLOR_MENU_TEXT},
- {"Scrollbar", SVG_COLOR_SCROLLBAR},
- {"ThreeDDarkShadow", SVG_COLOR_3D_DARK_SHADOW},
- {"ThreeDFace", SVG_COLOR_3D_FACE},
- {"ThreeDHighlight", SVG_COLOR_3D_HIGHLIGHT},
- {"ThreeDLightShadow", SVG_COLOR_3D_LIGHT_SHADOW},
- {"ThreeDShadow", SVG_COLOR_3D_SHADOW},
- {"Window", SVG_COLOR_WINDOW},
- {"WindowFrame", SVG_COLOR_WINDOW_FRAME},
- {"WindowText", SVG_COLOR_WINDOW_TEXT},
- };
- /* parses an color from a named color HTML or CSS 2 */
- static void svg_parse_named_color(SVG_Color *col, char *attribute_content)
- {
- u32 i, count;
- count = sizeof(predefined_colors) / sizeof(struct predef_col);
- for (i=0; i<count; i++) {
- if (!strcmp(attribute_content, predefined_colors[i].name)) {
- col->red = INT2FIX(predefined_colors[i].r) / 255;
- col->green = INT2FIX(predefined_colors[i].g) / 255;
- col->blue = INT2FIX(predefined_colors[i].b) / 255;
- col->type = SVG_COLOR_RGBCOLOR;
- return;
- }
- }
- count = sizeof(system_colors) / sizeof(struct sys_col);
- for (i=0; i<count; i++) {
- if (!strcmp(attribute_content, system_colors[i].name)) {
- col->type = system_colors[i].type;
- return;
- }
- }
- }
- const char *gf_svg_get_system_paint_server_name(u32 paint_type)
- {
- u32 i, count;
- count = sizeof(system_colors) / sizeof(struct sys_col);
- for (i=0; i<count; i++) {
- if (paint_type == system_colors[i].type) return system_colors[i].name;
- }
- return "undefined";
- }
- u32 gf_svg_get_system_paint_server_type(const char *name)
- {
- u32 i, count;
- count = sizeof(system_colors) / sizeof(struct sys_col);
- for (i=0; i<count; i++) {
- if (!strcmp(name, system_colors[i].name)) return system_colors[i].type;
- }
- return 0;
- }
- /* Reads an SVG Color
- either #RRGGBB, #RGB, rgb(r,g,b) in [0,255] , colorname, or 'r g b' in [0,1]
- ignores any space, comma, semi-column before and any space after
- TODO:
- transform the char into char and duplicate the input, instead of modifying it
- be more robust to errors in color description ex rgb(0 0 0)
- */
- static void svg_parse_color(SVG_Color *col, char *attribute_content)
- {
- char *str = attribute_content;
- while (str[strlen(attribute_content)-1] == ' ') str[strlen(attribute_content)-1] = 0;
- while (*str != 0 && (*str == ' ' || *str == ',' || *str == ';')) str++;
- if (!strcmp(str, "currentColor")) {
- col->type = SVG_COLOR_CURRENTCOLOR;
- return;
- } else if (!strcmp(str, "inherit")) {
- col->type = SVG_COLOR_INHERIT;
- return;
- } else if (str[0]=='#') {
- u32 val;
- sscanf(str+1, "%x", &val);
- if (strlen(str) == 7) {
- col->red = INT2FIX((val>>16) & 0xFF) / 255;
- col->green = INT2FIX((val>>8) & 0xFF) / 255;
- col->blue = INT2FIX(val & 0xFF) / 255;
- } else {
- col->red = INT2FIX((val>>8) & 0xF) / 15;
- col->green = INT2FIX((val>>4) & 0xF) / 15;
- col->blue = INT2FIX(val & 0xF) / 15;
- }
- col->type = SVG_COLOR_RGBCOLOR;
- } else if (strstr(str, "rgb(") || strstr(str, "RGB(")) {
- Float _val;
- u8 is_percentage= 0;
- if (strstr(str, "%")) is_percentage = 1;
- str = strstr(str, "(");
- str++;
- sscanf(str, "%f", &_val); col->red = FLT2FIX(_val);
- str = strstr(str, ",");
- if (!str) {
- /* space separated colors/percentages are not allowed neither in SVG 1.1 nor in SVG T1.2 */
- col->red = col->green = col->blue = 0;
- return;
- }
- str++;
- sscanf(str, "%f", &_val); col->green = FLT2FIX(_val);
- str = strstr(str, ",");
- if (!str) {
- /* space separated colors/percentages are not allowed neither in SVG 1.1 nor in SVG T1.2 */
- col->red = col->green = col->blue = 0;
- return;
- }
- str++;
- sscanf(str, "%f", &_val); col->blue = FLT2FIX(_val);
- if (is_percentage) {
- col->red /= 100;
- col->green /= 100;
- col->blue /= 100;
- } else {
- col->red /= 255;
- col->green /= 255;
- col->blue /= 255;
- }
- col->type = SVG_COLOR_RGBCOLOR;
- } else if ((str[0] >= 'a' && str[0] <= 'z')
- || (str[0] >= 'A' && str[0] <= 'Z')) {
- svg_parse_named_color(col, str);
- } else {
- Float _r, _g, _b;
- sscanf(str, "%f %f %f", &_r, &_g, &_b);
- col->red = FLT2FIX(_r);
- col->green = FLT2FIX(_g);
- col->blue = FLT2FIX(_b);
- col->type = SVG_COLOR_RGBCOLOR;
- }
- }
- /*
- Reads a number (i.e. without unit) according to the CSS syntax (same as SVG paths and transforms)
- trims any space, comma, semi-column before or after (TODO: fix this)
- reads an optional + or -
- then reads a digit between 0 and 9
- optionally followed by an '.' and digits between 0 and 9
- optionally followed by e or E and digits between 0 and 9
- Returns the number of chars read in d
- */
- static u32 svg_parse_number(char *d, Fixed *f, Bool is_angle)
- {
- u32 nb_digit_before = 0;
- u32 nb_digit_after = 0;
- Bool has_fractional = 0;
- Bool is_negative = 0;
- Float _val = 0;
- u32 i = 0;
- /* warning the comma and semicolumn should not be there when parsing a number in a path */
- while ((d[i] != 0) && strchr(" ,;\r\n\t", d[i])) i++;
- if (!d[i]) {
- GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Parsing] Parsing number with empty string or only spaces: %s\n", d));
- return 0;
- }
- if (d[i] == '+') {
- i++;
- } else if (d[i] == '-') {
- is_negative = 1;
- i++;
- }
- /* Warning: this is not normal, should be detected somehow by checking the BNF */
- /* if ((d[i]=='N') && (d[i+1]=='a') && (d[i+2]=='N')) {
- i+= 3;
- _val = 0;
- goto end;
- }*/
- /* read the digit-sequence token of the BNF */
- while (d[i] >= '0' && d[i] <= '9' && d[i] != 0) {
- _val = _val*10 + (d[i]-'0');
- nb_digit_before++;
- i++;
- }
- if (d[i] == '.') {
- has_fractional = 1;
- i++;
- while (d[i] >= '0' && d[i] <= '9' && d[i] != 0) {
- _val = _val*10 + (d[i]-'0');
- nb_digit_after++;
- i++;
- }
- if (nb_digit_after) {
- _val /= (Float)pow(10,nb_digit_after);
- } else if (nb_digit_before == 0) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error in parsing number (expecting digits before or after a '.': %s\n", d));
- return 0;
- } else {
- /* dangling '.' without digits after. This is allowed by the BNF */
- }
- }
- if ((nb_digit_before == 0) && (has_fractional == 0)) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error in parsing number (expecting digits):%s\n", d));
- return 0;
- }
- /* reading the exponent */
- if (d[i] == 'e' || d[i] == 'E') {
- Bool neg_exp = 0;
- u32 nb_exp_digits = 0;
- s32 exp = 0;
- i++;
- if (d[i] == '+') i++;
- else if (d[i] == '-') {
- i++;
- neg_exp=1;
- }
- while (d[i] >= '0' && d[i] <= '9' && d[i] != 0) {
- exp = exp*10 + (d[i]-'0');
- nb_exp_digits++;
- i++;
- }
- if (nb_exp_digits) {
- _val *= (Float)pow(10, neg_exp ? -exp : exp);
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error in parsing exponent, 'e' or 'E' should be followed by digits: %s\n", d));
- return 0;
- }
- }
- /* We can now produce the final number */
- if (is_negative) _val *= -1;
- if (is_angle) {
- _val/=180;
- (*f) = gf_mulfix(FLT2FIX(_val), GF_PI);
- } else {
- (*f) = FLT2FIX(_val);
- }
- /* warning the comma and semicolumn should not be there when parsing a path number */
- while (d[i] != 0 && (d[i] == ' ' || d[i] == ',' || d[i] == ';')) i++;
- return i;
- }
- /*
- Parse an Offset Value, i.e +/- Clock Value
- */
- static GF_Err svg_parse_clock_value(char *d, Double *clock_value)
- {
- char *tmp;
- s32 sign = 1;
- if (!d) return GF_BAD_PARAM;
- if (!d[0]) return GF_BAD_PARAM;
- if (d[0] == '+') d++;
- else if (d[0] == '-') { sign = -1; d++; }
- if (!d[0]) return GF_BAD_PARAM;
- /* According to SVG, the following are invalid syntaxes (see animate-elem-225-t.svg)
- '+-2s'
- '1++s' even though sscanf returns the right values
- */
- if (strchr(d, '+') || strchr(d, '-')) return GF_BAD_PARAM;
- /* No embedded white space is allowed in clock values,
- although leading and trailing white space characters will be ignored.*/
- while (*d == ' ') d++;
- if ((tmp = strchr(d, ':'))) {
- /* Full or Partial Clock value */
- tmp++;
- if ((tmp = strchr(tmp, ':'))) {
- /* Full Clock value : hh:mm:ss(.frac) */
- u32 hours;
- u32 minutes;
- Float seconds;
- if (sscanf(d, "%u:%u:%f", &hours, &minutes, &seconds) < 3) return GF_BAD_PARAM;
- *clock_value = hours*3600 + minutes*60 + seconds;
- } else {
- /* Partial Clock value : mm:ss(.frac) */
- s32 minutes;
- Float seconds;
- if (sscanf(d, "%d:%f", &minutes, &seconds) < 2) return GF_BAD_PARAM;
- *clock_value = minutes*60 + seconds;
- }
- } else if ((tmp = strstr(d, "h"))) {
- Float f;
- if (sscanf(d, "%fh", &f) == 0) return GF_BAD_PARAM;
- *clock_value = 3600*f;
- } else if (strstr(d, "min")) {
- Float f;
- if (sscanf(d, "%fmin", &f) == 0) return GF_BAD_PARAM;
- *clock_value = 60*f;
- } else if ((tmp = strstr(d, "ms"))) {
- Float f;
- if (sscanf(d, "%fms", &f) == 0) return GF_BAD_PARAM;
- *clock_value = f/1000;
- } else if (strchr(d, 's')) {
- Float f;
- if (sscanf(d, "%fs", &f) == 0) return GF_BAD_PARAM;
- *clock_value = f;
- } else {
- Float f;
- if (sscanf(d, "%f", &f) == 0) return GF_BAD_PARAM;
- *clock_value = f;
- }
- *clock_value *= sign;
- return GF_OK;
- }
- /* Parses one SVG time value:
- indefinite,
- element_id.event_name
- wallclock,
- accessKey,
- events,
- clock value.
- */
- static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d)
- {
- GF_Err e = GF_OK;
- char *tmp;
- /* Offset Values */
- if ((d[0] >= '0' && d[0] <= '9') || d[0] == '+' || d[0] == '-'){
- v->type = GF_SMIL_TIME_CLOCK;
- return svg_parse_clock_value(d, &(v->clock));
- }
- /* Indefinite Values */
- else if (!strcmp(d, "indefinite")) {
- v->type = GF_SMIL_TIME_INDEFINITE;
- return GF_OK;
- }
- /* Wallclock Values */
- else if ((tmp = strstr(d, "wallclock("))) {
- u32 year, month, day;
- u32 hours, minutes;
- u32 nhours, nminutes;
- Float seconds;
- char *tmp1, *tmp2;
- v->type = GF_SMIL_TIME_WALLCLOCK;
- tmp += 10;
- if ((tmp1 = strchr(tmp, 'T')) ) {
- /* From tmp to wallStartTime, we parse a date */
- sscanf(tmp, "%u-%u-%dT", &year, &month, &day);
- tmp1++;
- tmp = tmp1;
- }
- if ((tmp1 = strchr(tmp, ':')) ) {
- if ((tmp2 = strchr(tmp1, ':')) ) {
- /* HHMMSS */
- sscanf(tmp, "%u:%u:%f", &hours, &minutes, &seconds);
- } else {
- /* HHMM */
- sscanf(tmp, "%u:%u", &hours, &minutes);
- }
- }
- if (strchr(tmp, 'Z')) {
- return GF_OK;
- } else {
- if ( (tmp1 = strchr(tmp, '+')) ) {
- sscanf(tmp1, "%u:%u", &nhours, &nminutes);
- } else if ( (tmp1 = strchr(tmp, '-')) ) {
- sscanf(tmp1, "%u:%u", &nhours, &nminutes);
- }
- }
- return GF_OK;
- }
- /* AccessKey Values */
- else if ((tmp = strstr(d, "accessKey("))) {
- char *sep;
- v->type = GF_SMIL_TIME_EVENT;
- v->event.type = GF_EVENT_KEYDOWN;
- v->element = elt->sgprivate->scenegraph->RootNode;
- tmp+=10;
- sep = strchr(d, ')');
- sep[0] = 0;
- v->event.parameter = gf_dom_get_key_type(tmp);
- sep++;
- if ((tmp = strchr(sep, '+')) || (tmp = strchr(sep, '-'))) {
- char c = *tmp;
- tmp++;
- e = svg_parse_clock_value(tmp, &(v->clock));
- if (c == '-') v->clock *= -1;
- }
- return e;
- }
- else {
- Bool had_param = 0;
- char *tmp2;
- v->type = GF_SMIL_TIME_EVENT;
- if ((tmp = strchr(d, '.'))) {
- tmp[0] = 0;
- if (strlen(d) == 0) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] expecting an id before '.' in SMIL Time .%s\n", tmp+1));
- return GF_BAD_PARAM;
- }
- v->element_id = gf_strdup(d);
- tmp[0] = '.';
- tmp++;
- } else {
- tmp = d;
- }
- if ((tmp2 = strchr(tmp, '('))) {
- tmp2[0] = 0;
- v->event.type = gf_dom_event_type_by_name(tmp);
- tmp2[0] = '(';
- tmp2++;
- had_param = 1;
- v->event.parameter = atoi(tmp2);
- tmp = strchr(tmp2, ')');
- if (!tmp) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] expecting ')' in SMIL Time %s\n", d));
- return GF_BAD_PARAM;
- }
- tmp++;
- }
- if ((tmp2 = strchr(tmp, '+')) || (tmp2 = strchr(tmp, '-'))) {
- char c = *tmp2;
- char *tmp3 = tmp2;
- tmp2[0] = 0;
- tmp3--;
- while (*tmp3==' ') { *tmp3=0; tmp3--; }
- if (v->event.type == 0) v->event.type = gf_dom_event_type_by_name(tmp);
- if (!had_param && (v->event.type == GF_EVENT_REPEAT || v->event.type == GF_EVENT_REPEAT_EVENT))
- v->event.parameter = 1;
- tmp2[0] = c;
- tmp2++;
- e = svg_parse_clock_value(tmp2, &(v->clock));
- if (c == '-') v->clock *= -1;
- return e;
- } else {
- if (v->event.type == 0) v->event.type = gf_dom_event_type_by_name(tmp);
- if (!had_param && (v->event.type == GF_EVENT_REPEAT || v->event.type == GF_EVENT_REPEAT_EVENT))
- v->event.parameter = 1;
- }
- }
- return GF_OK;
- }
- /* Parses a list of SVG transformations and collapses them in the given matrix */
- Bool gf_svg_parse_transformlist(GF_Matrix2D *mat, char *attribute_content)
- {
- GF_Matrix2D tmp;
- char *str;
- u32 read_chars;
- u32 i;
- gf_mx2d_init(*mat);
- str = attribute_content;
- i = 0;
- while (str[i] != 0) {
- while (str[i] == ' ') i++;
- if (str[i] == ',') i++;
- while (str[i] == ' ') i++;
- if (strstr(str+i, "scale")==str+i) {
- i += 5;
- while(str[i] == ' ') i++;
- if (str[i] == '(') {
- Fixed sx, sy;
- i++;
- read_chars = svg_parse_number(&(str[i]), &sx, 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading sx component in scale: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- if (str[i] == ')') {
- sy = sx;
- } else {
- read_chars = svg_parse_number(&(str[i]), &sy, 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading sy component in scale: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- }
- gf_mx2d_init(tmp);
- gf_mx2d_add_scale(&tmp, sx, sy);
- gf_mx2d_add_matrix(&tmp, mat);
- gf_mx2d_copy(*mat, tmp);
- while(str[i] == ' ') i++;
- if (str[i] == ')') i++;
- else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else if (strstr(str+i, "translate")==str+i) {
- i += 9;
- while(str[i] == ' ') i++;
- if (str[i] == '(') {
- Fixed tx, ty;
- i++;
- read_chars = svg_parse_number(&(str[i]), &tx, 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading tx component in translate: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- if (str[i] == ')') {
- ty = 0;
- } else {
- read_chars = svg_parse_number(&(str[i]), &ty, 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading ty component in translate: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- }
- gf_mx2d_init(tmp);
- gf_mx2d_add_translation(&tmp, tx, ty);
- gf_mx2d_add_matrix(&tmp, mat);
- gf_mx2d_copy(*mat, tmp);
- while(str[i] == ' ') i++;
- if (str[i] == ')') i++;
- else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else if (strstr(str+i, "rotate")==str+i) {
- i += 6;
- while(str[i] == ' ') i++;
- if (str[i] == '(') {
- Fixed angle, cx, cy;
- i++;
- read_chars = svg_parse_number(&(str[i]), &angle, 1);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading angle component in rotate: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- if (str[i] == ')') {
- cx = cy = 0;
- } else {
- read_chars = svg_parse_number(&(str[i]), &cx, 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading cx component in rotate: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- read_chars = svg_parse_number(&(str[i]), &cy, 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading cy component in rotate: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- }
- gf_mx2d_init(tmp);
- gf_mx2d_add_rotation(&tmp, cx, cy, angle);
- gf_mx2d_add_matrix(&tmp, mat);
- gf_mx2d_copy(*mat, tmp);
- while(str[i] == ' ') i++;
- if (str[i] == ')') i++;
- else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else if (strstr(str+i, "skewX")==str+i) {
- i += 5;
- while(str[i] == ' ') i++;
- if (str[i] == '(') {
- Fixed angle;
- i++;
- read_chars = svg_parse_number(&(str[i]), &angle, 1);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading angle in skewX: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- gf_mx2d_init(tmp);
- gf_mx2d_add_skew_x(&tmp, angle);
- gf_mx2d_add_matrix(&tmp, mat);
- gf_mx2d_copy(*mat, tmp);
- while(str[i] == ' ') i++;
- if (str[i] == ')') i++;
- else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else if (strstr(str+i, "skewY")==str+i) {
- i += 5;
- while(str[i] == ' ') i++;
- if (str[i] == '(') {
- Fixed angle;
- i++;
- read_chars = svg_parse_number(&(str[i]), &angle, 1);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading angle component in skewY: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- gf_mx2d_init(tmp);
- gf_mx2d_add_skew_y(&tmp, angle);
- gf_mx2d_add_matrix(&tmp, mat);
- gf_mx2d_copy(*mat, tmp);
- while(str[i] == ' ') i++;
- if (str[i] == ')') i++;
- else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else if (strstr(str+i, "matrix")==str+i) {
- i+=6;
- while(str[i] == ' ') i++;
- if (str[i] == '(') {
- i++;
- read_chars = svg_parse_number(&(str[i]), &(tmp.m[0]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient a in matrix: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- read_chars = svg_parse_number(&(str[i]), &(tmp.m[3]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient b in matrix: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- read_chars = svg_parse_number(&(str[i]), &(tmp.m[1]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient c in matrix: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- read_chars = svg_parse_number(&(str[i]), &(tmp.m[4]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient d in matrix: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- read_chars = svg_parse_number(&(str[i]), &(tmp.m[2]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient e in matrix: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- read_chars = svg_parse_number(&(str[i]), &(tmp.m[5]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient f in matrix: %s\n", attribute_content));
- return 0;
- }
- i += read_chars;
- gf_mx2d_add_matrix(&tmp, mat);
- gf_mx2d_copy(*mat, tmp);
- while(str[i] == ' ') i++;
- if (str[i] == ')') i++;
- else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content));
- return 0;
- }
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Unrecognized transofrm type in attribute %s\n", attribute_content));
- return 0;
- }
- /*for svgView parsing*/
- if (str[i] == ')') i++;
- }
- return 1;
- }
- /* Parses an SVG transform attribute and collapses all in the given matrix */
- static Bool svg_parse_transform(SVG_Transform *t, char *attribute_content)
- {
- char *str;
- u32 i;
- u32 read_chars;
- str = attribute_content;
- i = 0;
- if ((str = strstr(attribute_content, "ref"))) {
- t->is_ref = 1;
- gf_mx2d_init(t->mat);
- str+=2;
- while (str[i] == ' ') i++;
- if (str[i] == '(') {
- i++;
- while (str[i] == ' ') i++;
- if (str[i] == 's' && str[i+1] == 'v' && str[i+2] == 'g') {
- i+=3;
- while (str[i] == ' ') i++;
- if (str[i] == ',') {
- i++;
- } else if (str[i] == ')') {
- i++;
- return GF_OK;
- }
- read_chars = svg_parse_number(&(str[i]), &(t->mat.m[2]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient tx in ref transform: %s\n", attribute_content));
- return GF_BAD_PARAM;
- }
- i += read_chars;
- read_chars = svg_parse_number(&(str[i]), &(t->mat.m[5]), 0);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient ty in ref transform: %s\n", attribute_content));
- return GF_BAD_PARAM;
- }
- i += read_chars;
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Unsupported syntax for ref transform attribute"));
- }
- while (str[i] == ' ') i++;
- if (str[i] == ')') i++;
- else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content));
- }
- return GF_OK;
- } else {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in ref transform attribute: %s\n", attribute_content));
- return GF_BAD_PARAM;
- }
- } else {
- read_chars = gf_svg_parse_transformlist(&t->mat, attribute_content);
- if (!read_chars) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error parsing transform list: %s\n", attribute_content));
- return GF_BAD_PARAM;
- }
- }
- return GF_OK;
- }
- #undef REMOVE_ALLOC
- #if USE_GF_PATH
- //#define PARSE_PATH_ONLY
- static void svg_parse_path(SVG_PathData *path, char *attribute_content)
- {
- char *d = attribute_content;
- /* used to detect end of BNF production:
- "The processing of the BNF must consume as much of a given BNF production as possible,
- stopping at the point when a character is encountered which no longer satisfies the production." */
- u32 read_chars = 0;
- /* Point used to start a new subpath when the previous subpath is closed */
- SVG_Point prev_m_pt;
- /* Point used to convert relative 'lower-case commands' into absolute */
- SVG_Point rel_ref_pt;
- /* Points used to convert S, T commands into C, Q */
- SVG_Point orig, ct_orig, ct_end, end;
- /* Used by elliptical arcs */
- Fixed x_axis_rotation, large_arc_flag, sweep_flag;
- char c, prev_c;
- u32 i;
- if (*d == 0) return;
- i = 0;
- prev_c = 'M';
- orig.x = orig.y = ct_orig.x = ct_orig.y = prev_m_pt.x = prev_m_pt.y = rel_ref_pt.x = rel_ref_pt.y = end.x = end.y = 0;
- while(1) {
- while ( (d[i]==' ') || (d[i] =='\t') || (d[i] =='\r') || (d[i] =='\n') ) i++;
- c = d[i];
- if (! c) break;
- next_command:
- switch (c) {
- case 'm':
- case 'M':
- i++;
- read_chars = svg_parse_number(&(d[i]), &(orig.x), 0);
- if (!read_chars) return;
- i += read_chars;
- read_chars = svg_parse_number(&(d[i]), &(orig.y), 0);
- if (!read_chars) return;
- i += read_chars;
- if (c == 'm') {
- orig.x += rel_ref_pt.x;
- orig.y += rel_ref_pt.y;
- }
- #ifndef PARSE_PATH_ONLY
- gf_path_add_move_to(path, orig.x, orig.y);
- #endif
- rel_ref_pt = orig;
- prev_m_pt = orig;
- /*provision for nextCurveTo when no curve is specified:
- "If there is no previous command or if the previous command was not an C, c, S or s,
- assume the first control point is coincident with the current point.
- */
- ct_orig = orig;
- prev_c = c;
- break;
- case 'L':
- case 'l':
- i++;
- read_chars = svg_parse_number(&(d[i]), &(orig.x), 0);
- if (!read_chars) return;
- i += read_chars;
- read_chars = svg_parse_number(&(d[i]), &(orig.y), 0);
- if (!read_chars) return;
- i += read_chars;
- if (c == 'l') {
- orig.x += rel_ref_pt.x;
- orig.y += rel_ref_pt.y;
- }
- #ifndef PARSE_PATH_ONLY
- gf_path_add_line_to(path, orig.x, orig.y);
- #endif
- rel_ref_pt = orig;
- orig = end;
- /*cf above*/
- ct_orig = orig;
- prev_c = c;
- break;
- case 'H':
- case 'h':
- i++;
- read_chars = svg_parse_number(&(d[i]), &(orig.x), 0);
- if (!read_chars) return;
- i += read_chars;
- if (c == 'h') {
- orig.x += rel_ref_pt.x;
- }
- orig.y = rel_ref_pt.y;
- #ifndef PARSE_PATH_ONLY
- gf_path_add_line_to(path, orig.x, orig.y);
- #endif
- rel_ref_pt.x = orig.x;
- orig = end;
- /*cf above*/
- ct_orig = orig;
- prev_c = c;
- break;
- case 'V':
- case 'v':
- i++;
- read_chars = svg_parse_number(&(d[i]), &(orig.y), 0);
- if (!read_chars) return;
- i += read_chars;
- if (c == 'v') {
- orig.y += rel_ref_pt.y;
- }
- orig.x = rel_ref_pt.x;
- #ifndef PARSE_PATH_ONLY
- gf_path_add_line_to(path, orig.x, orig.y);
- #endif
- rel_ref_pt.y = orig.y;
- orig = end;
- /*cf above*/
- ct_orig …
Large files files are truncated, but you can click here to view the full file