[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11340: Case-insensitive HTML parsin
From: |
Bob Naugle |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11340: Case-insensitive HTML parsing. |
Date: |
Thu, 30 Jul 2009 02:07:31 -0600 |
User-agent: |
Bazaar (1.13.1) |
------------------------------------------------------------
revno: 11340
committer: Bob Naugle <address@hidden>
branch nick: trunk
timestamp: Thu 2009-07-30 02:07:31 -0600
message:
Case-insensitive HTML parsing.
HTML <textformat> tag.
Other HTML fixes.
modified:
libcore/TextField.cpp
libcore/TextField.h
=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp 2009-07-29 21:55:54 +0000
+++ b/libcore/TextField.cpp 2009-07-30 08:07:31 +0000
@@ -53,6 +53,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/bind.hpp>
#include <cstdlib>
+#include <ctype.h>
#include <typeinfo>
#include <map>
@@ -425,12 +426,13 @@
TextField::on_event(const event_id& ev)
{
if (isReadOnly()) return false;
-
+
switch (ev.id())
{
case event_id::KEY_PRESS:
{
if ( getType() != typeInput ) break; // not an input field
+ setHtml(false); //editable html fields are not yet implemented
std::wstring s = _text;
// id.keyCode is the unique gnash::key::code for a
DisplayObject/key.
@@ -701,6 +703,30 @@
return utf8::encodeCanonicalString(_text, version);
}
+void
+TextField::setTextFormat(TextFormat_as tf)
+{
+ //TODO: this is lazy. we should set all the TextFormat variables HERE, i
think
+ //This is just so we can set individual variables without having to call
format_text()
+ //This calls format_text() at the end of setting TextFormat
+ if ( tf.alignDefined() ) setAlignment(tf.align());
+ if ( tf.sizeDefined() ) setFontHeight(tf.size()); // keep twips
+ if ( tf.indentDefined() ) setIndent(tf.indent());
+ if ( tf.blockIndentDefined() ) setBlockIndent(tf.blockIndent());
+ if ( tf.leadingDefined() ) setLeading(tf.leading());
+ if ( tf.leftMarginDefined() ) setLeftMargin(tf.leftMargin());
+ if ( tf.rightMarginDefined() ) setRightMargin(tf.rightMargin());
+ if ( tf.colorDefined() ) setTextColor(tf.color());
+ if ( tf.underlinedDefined() ) setUnderlined(tf.underlined());
+
+ // ADDED (completed)
+ if ( tf.bulletDefined() ) setBullet(tf.bullet());
+ if ( tf.displayDefined() ) setDisplay(tf.display());
+ if ( tf.tabStopsDefined() ) setTabStops(tf.tabStops());
+
+ format_text();
+}
+
bool
TextField::set_member(string_table::key name,
const as_value& val, string_table::key nsname, bool ifFound)
@@ -1312,7 +1338,7 @@
}
// new paragraphs get the indent.
- x = std::max(0, getLeftMargin() + getIndent()) + PADDING_TWIPS;
+ x = std::max(0, getLeftMargin() + getIndent() + getBlockIndent()) +
PADDING_TWIPS;
y += div * (getFontHeight() + leading);
// Start a new record on the next line. Other properties of the
@@ -1464,93 +1490,182 @@
bool complete = parseHTML(discard, attributes, it, e,
selfclosing);
std::string s(discard.begin(), discard.end());
s.assign(discard.begin(), discard.end());
- if (!complete) continue;
- else {
+ if (!complete) {
+ //parsing went wrong
+ continue;
+ } else {
//Don't think this is the best way to match with
tags...
//Also, assumes tags are properly nested. This is
acceptable
//assumption
- if (s == "u") {
+ if (s == "U") {
//underline
newrec.setUnderline(true);
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
- } else if (s == "a") {
+ } else if (s == "A") {
//anchor
log_unimpl("<a> html tag in TextField");
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
- } else if (s == "b") {
+ } else if (s == "B") {
//bold
Font* boldfont = new Font(rec.getFont()->name(),
true, rec.getFont()->isItalic());
newrec.setFont(boldfont);
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
- } else if (s == "font") {
+ } else if (s == "FONT") {
//font
boost::uint16_t originalsize = _fontHeight;
- if (attributes.find("color") != attributes.end()) {
+ if (attributes.find("COLOR") != attributes.end()) {
+ //font COLOR attribute
boost::uint8_t r = std::strtol(
- attributes["color"].substr(1,2).data(),
NULL, 16);
+ attributes["COLOR"].substr(1,2).data(),
NULL, 16);
boost::uint8_t g = std::strtol(
- attributes["color"].substr(3,2).data(),
NULL, 16);
+ attributes["COLOR"].substr(3,2).data(),
NULL, 16);
boost::uint8_t b = std::strtol(
- attributes["color"].substr(5,2).data(),
NULL, 16);
+ attributes["COLOR"].substr(5,2).data(),
NULL, 16);
boost::uint8_t a = 255; //alpha not given in
color attribute
rgba color(r,g,b,a);
newrec.setColor(color);
}
- if (attributes.find("face") != attributes.end()) {
- Font* newfont = new Font(attributes["face"],
+ if (attributes.find("FACE") != attributes.end()) {
+ //font FACE attribute
+ Font* newfont = new Font(attributes["FACE"],
rec.getFont()->isBold(),
rec.getFont()->isItalic());
newrec.setFont(newfont);
}
- if (attributes.find("size") != attributes.end()) {
- std::string firstchar =
attributes["size"].substr(0,1);
+ if (attributes.find("SIZE") != attributes.end()) {
+ //font SIZE attribute
+ std::string firstchar =
attributes["SIZE"].substr(0,1);
if (firstchar == "+") {
newrec.setTextHeight(rec.textHeight() +
-
*(attributes["size"].substr(1,attributes["size"].length()-1).data()));
+ (20 * std::strtol(
+
attributes["SIZE"].substr(1,attributes["SIZE"].length()-1).data(),
+ NULL,10)));
+ newrec.setYOffset(PADDING_TWIPS +
+ newrec.textHeight() +
+ (fontLeading - fontDescent));
+ _fontHeight += 20 * std::strtol(
+
attributes["SIZE"].substr(1,attributes["SIZE"].length()-1).data(),
+ NULL,10);
} else if (firstchar == "-") {
newrec.setTextHeight(rec.textHeight() -
-
*(attributes["size"].substr(1,attributes["size"].length()-1).data()));
+ (20 * std::strtol(
+
attributes["SIZE"].substr(1,attributes["SIZE"].length()-1).data(),
+ NULL,10)));
+ newrec.setYOffset(PADDING_TWIPS +
+ newrec.textHeight() +
+ (fontLeading - fontDescent));
+ _fontHeight -= 20 * std::strtol(
+
attributes["SIZE"].substr(1,attributes["SIZE"].length()-1).data(),
+ NULL,10);
} else {
newrec.setTextHeight(20 * std::strtol(
- attributes["size"].data(), NULL, 10));
- newrec.setYOffset(PADDING_TWIPS +
newrec.textHeight() + (fontLeading - fontDescent));
+ attributes["SIZE"].data(), NULL, 10));
+ newrec.setYOffset(PADDING_TWIPS +
newrec.textHeight() +
+ (fontLeading - fontDescent));
_fontHeight = 20 * std::strtol(
- attributes["size"].data(), NULL, 10);
+ attributes["SIZE"].data(), NULL, 10);
}
}
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
_fontHeight = originalsize;
-
- } else if (s == "img") {
+ y = newrec.yOffset();
+ } else if (s == "IMG") {
//image
log_unimpl("<img> html tag in TextField");
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
- } else if (s == "i") {
+ } else if (s == "I") {
//italic
Font* italicfont = new Font(rec.getFont()->name(),
rec.getFont()->isBold(), true);
newrec.setFont(italicfont);
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
- } else if (s == "li") {
+ } else if (s == "LI") {
//list item (bullet)
log_unimpl("<li> html tag in TextField");
- } else if (s == "span") {
+ } else if (s == "SPAN") {
//span
log_unimpl("<span> html tag in TextField");
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
- } else if (s == "textformat") {
- //text format
+ } else if (s == "TEXTFORMAT") {
+ //textformat
log_unimpl("<textformat> html tag in TextField");
+ boost::uint16_t originalblockindent =
getBlockIndent();
+ boost::uint16_t originalindent = getIndent();
+ boost::uint16_t originalleading = getLeading();
+ boost::uint16_t originalleftmargin =
getLeftMargin();
+ boost::uint16_t originalrightmargin =
getRightMargin();
+ std::vector<int> originaltabstops = getTabStops();
+ if (attributes.find("BLOCKINDENT") !=
attributes.end()) {
+ //textformat BLOCKINDENT attribute
+ setBlockIndent(20 * std::strtol(
+ attributes["BLOCKINDENT"].data(),
NULL, 10));
+ if (newrec.xOffset() == std::max(0,
originalleftmargin +
+ originalindent + originalblockindent) +
PADDING_TWIPS) {
+ //if beginning of line, indent
+ x = std::max(0, getLeftMargin() +
+ getIndent() + getBlockIndent())
+ + PADDING_TWIPS;
+ newrec.setXOffset(x);
+ }
+ }
+ if (attributes.find("INDENT") != attributes.end())
{
+ //textformat INDENT attribute
+ setIndent(20 * std::strtol(
+ attributes["INDENT"].data(), NULL, 10));
+ if (newrec.xOffset() == std::max(0,
originalleftmargin +
+ originalindent + getBlockIndent()) +
PADDING_TWIPS) {
+ //if beginning of line, indent
+ x = std::max(0, getLeftMargin() +
+ getIndent() + getBlockIndent())
+ + PADDING_TWIPS;
+ newrec.setXOffset(x);
+ }
+ }
+ if (attributes.find("LEADING") !=
attributes.end()) {
+ //textformat LEADING attribute
+ setLeading(20 * std::strtol(
+ attributes["LEADING"].data(), NULL,
10));
+ }
+ if (attributes.find("LEFTMARGIN") !=
attributes.end()) {
+ //textformat LEFTMARGIN attribute
+ setLeftMargin(20 * std::strtol(
+ attributes["LEFTMARGIN"].data(), NULL,
10));
+ if (newrec.xOffset() == std::max(0,
originalleftmargin +
+ getIndent() + getBlockIndent()) +
PADDING_TWIPS) {
+ //if beginning of line, indent
+ x = std::max(0, getLeftMargin() +
+ getIndent() + getBlockIndent())
+ + PADDING_TWIPS;
+ newrec.setXOffset(x);
+ }
+ }
+ if (attributes.find("RIGHTMARGIN") !=
attributes.end()) {
+ //textformat RIGHTMARGIN attribute
+ setRightMargin(20 * std::strtol(
+ attributes["RIGHTMARGIN"].data(),
NULL, 10));
+ //FIXME:Should not apply this to this line if
we are not at
+ //beginning of line. Not sure how to do that.
+ }
+ if (attributes.find("TABSTOPS") !=
attributes.end()) {
+ //textformat TABSTOPS attribute
+ log_unimpl("html <textformat> tag tabstops
attribute");
+ }
handleChar(it, e, x, y, newrec, last_code,
last_space_glyph, last_line_start_record);
- } else if (s == "p") {
+ setBlockIndent(originalblockindent);
+ setIndent(originalindent);
+ setLeading(originalleading);
+ setLeftMargin(originalleftmargin);
+ setRightMargin(originalrightmargin);
+ setTabStops(originaltabstops);
+ } else if (s == "P") {
//paragraph
if (_display == BLOCK)
{
@@ -1568,7 +1683,7 @@
last_space_glyph,
last_line_start_record);
}
- } else if (s == "br") {
+ } else if (s == "BR") {
//line break
newLine(it, x, y, rec,
last_space_glyph,
last_line_start_record, 1.0,false);
@@ -1711,7 +1826,7 @@
_textRecords.push_back(rec);
float previous_x = x;
- x = std::max(0, getLeftMargin() + getIndent()) + PADDING_TWIPS;
+ x = std::max(0, getLeftMargin() + getBlockIndent()) +
PADDING_TWIPS;
y += _fontHeight + leading;
// Start a new record on the next line.
@@ -1961,6 +2076,20 @@
std::string attname;
std::string attvalue;
while (it != e && *it != ' ') {
+ if (*it == '/') {
+ ++it;
+ if (*it == '>') {
+ ++it;
+ selfclosing = true;
+ return true;
+ } else {
+ while (it != e) {
+ ++it;
+ }
+ log_error("invalid html tag");
+ return false;
+ }
+ }
if (*it == '>') {
++it;
return true;
@@ -1968,10 +2097,10 @@
// Check for NULL DisplayObject
if (*it == 0) {
- log_error("found NULL DisplayObject in htmlText");
- return false;
- }
- tag.push_back(*it);
+ log_error("found NULL DisplayObject in htmlText");
+ return false;
+ }
+ tag.push_back(toupper(*it));
++it;
}
while (it != e && *it == ' ') {
@@ -2000,87 +2129,87 @@
while (it != e && *it != '=' && *it != ' ') {
if (*it == 0) {
- log_error("found NULL DisplayObject in htmlText");
- return false;
+ log_error("found NULL DisplayObject in htmlText");
+ return false;
}
if (*it == '>') {
- log_error("malformed HTML tag, invalid attribute name");
- while (it != e) {
- ++it;
- }
- return false;
- }
-
- attname.push_back(*it);
- ++it;
- }
- while (it != e && (*it == ' ' || *it == '=')) {
- ++it; //skip over spaces and '='
- }
- if (it != e) {
- if (*it != '"') { //make sure attribute value is opened with '"'
- log_error("attribute value must be opened with \'\"\' (did you
remember escape char?)");
- while (it != e) {
- ++it;
- }
- return false;
- } else {
- ++it; //skip (")
- }
- }
- while (it != e && *it != '"') { //get attribute value
-
- if (*it == 0) {
- log_error("found NULL DisplayObject in htmlText");
- return false;
- }
-
- attvalue.push_back(*it);
- ++it;
- }
- if (it != e) {
- if (*it != '"') { //make sure attribute value is closed with '"'
- log_error("attribute value must be closed with \'\"\' (did you
remember escape char?)");
- while (it != e) {
- ++it;
- }
- return false;
- } else {
- ++it; //skip (")
- }
- }
- attributes.insert( std::pair<std::string,std::string>(attname,
attvalue));
- attname = "";
- attvalue = "";
- if ((*it != ' ') && (*it != '/') && (*it != '>')) {
- log_error("malformed HTML tag, invalid attribute value");
- while (it != e) {
- ++it;
- }
- return false;
- }
- if (*it == ' ') {
- while (it != e && *it == ' ') {
- ++it; //skip over spaces
- }
- }
- if (*it == '>') {
- ++it;
- return true;
- } else if (*it == '/') {
- ++it;
- if (*it == '>') {
- ++it;
- selfclosing = true;
+ log_error("malformed HTML tag, invalid attribute name");
+ while (it != e) {
+ ++it;
+ }
+ return false;
+ }
+
+ attname.push_back(toupper(*it));
+ ++it;
+ }
+ while (it != e && (*it == ' ' || *it == '=')) {
+ ++it; //skip over spaces and '='
+ }
+ if (it != e) {
+ if (*it != '"') { //make sure attribute value is opened with '"'
+ log_error("attribute value must be opened with \'\"\' (did you
remember escape char?)");
+ while (it != e) {
+ ++it;
+ }
+ return false;
+ } else {
+ ++it; //skip (")
+ }
+ }
+ while (it != e && *it != '"') { //get attribute value
+
+ if (*it == 0) {
+ log_error("found NULL DisplayObject in htmlText");
+ return false;
+ }
+
+ attvalue.push_back(toupper(*it));
+ ++it;
+ }
+ if (it != e) {
+ if (*it != '"') { //make sure attribute value is closed with '"'
+ log_error("attribute value must be closed with \'\"\' (did you
remember escape char?)");
+ while (it != e) {
+ ++it;
+ }
+ return false;
+ } else {
+ ++it; //skip (")
+ }
+ }
+ attributes.insert( std::pair<std::string,std::string>(attname,
attvalue));
+ attname = "";
+ attvalue = "";
+ if ((*it != ' ') && (*it != '/') && (*it != '>')) {
+ log_error("malformed HTML tag, invalid attribute value");
+ while (it != e) {
+ ++it;
+ }
+ return false;
+ }
+ if (*it == ' ') {
+ while (it != e && *it == ' ') {
+ ++it; //skip over spaces
+ }
+ }
+ if (*it == '>') {
+ ++it;
return true;
- } else {
- while (it != e) {
- ++it;
- }
- log_error("invalid html tag");
- return false;
- }
- }
+ } else if (*it == '/') {
+ ++it;
+ if (*it == '>') {
+ ++it;
+ selfclosing = true;
+ return true;
+ } else {
+ while (it != e) {
+ ++it;
+ }
+ log_error("invalid html tag");
+ return false;
+ }
+ }
}
#ifdef GNASH_DEBUG_TEXTFIELDS
@@ -2277,13 +2406,12 @@
}
void
-TextField::setLeading(boost::uint16_t h)
+TextField::setLeading(boost::int16_t h)
{
if ( _leading != h )
{
set_invalidated();
_leading = h;
- format_text();
}
}
@@ -2294,7 +2422,6 @@
{
set_invalidated();
_underlined = v;
- format_text();
}
}
@@ -2303,7 +2430,6 @@
{
if (_bullet != b) {
_bullet = b;
- format_text();
}
}
@@ -2316,7 +2442,6 @@
_tabStops[i] = PIXEL_RATIO * tabStops[i];
}
- format_text();
set_invalidated();
}
@@ -2368,7 +2493,6 @@
{
set_invalidated();
_indent = h;
- format_text();
}
}
@@ -2379,7 +2503,6 @@
{
set_invalidated();
_blockIndent = h;
- format_text();
}
}
@@ -2390,7 +2513,6 @@
{
set_invalidated();
_rightMargin = h;
- format_text();
}
}
@@ -2401,7 +2523,6 @@
{
set_invalidated();
_leftMargin = h;
- format_text();
}
}
@@ -2412,7 +2533,6 @@
{
set_invalidated();
_fontHeight = h;
- format_text();
}
}
@@ -2508,7 +2628,7 @@
else if ( _autoSize == autoSizeRight ) textAlignment = ALIGN_RIGHT;
return textAlignment;
}
-
+
void
TextField::onChanged()
{
@@ -3064,21 +3184,6 @@
);
return as_value();
}
-
- if ( tf->alignDefined() ) text->setAlignment(tf->align());
- if ( tf->sizeDefined() ) text->setFontHeight(tf->size()); // keep twips
- if ( tf->indentDefined() ) text->setIndent(tf->indent());
- if ( tf->blockIndentDefined() ) text->setBlockIndent(tf->blockIndent());
- if ( tf->leadingDefined() ) text->setLeading(tf->leading());
- if ( tf->leftMarginDefined() ) text->setLeftMargin(tf->leftMargin());
- if ( tf->rightMarginDefined() ) text->setRightMargin(tf->rightMargin());
- if ( tf->colorDefined() ) text->setTextColor(tf->color());
- if ( tf->underlinedDefined() ) text->setUnderlined(tf->underlined());
-
- // ADDED (completed)
- if ( tf->bulletDefined() ) text->setBullet(tf->bullet());
- if ( tf->displayDefined() ) text->setDisplay(tf->display());
- if ( tf->tabStopsDefined() ) text->setTabStops(tf->tabStops());
if (isAS3(fn)) {
// TODO: current font finding assumes we have a parent, which isn't
@@ -3111,6 +3216,7 @@
LOG_ONCE( log_unimpl("TextField.setTextFormat() discards url and target")
);
+ text->setTextFormat(*tf);
return as_value();
}
=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h 2009-07-29 18:13:21 +0000
+++ b/libcore/TextField.h 2009-07-30 08:07:31 +0000
@@ -24,6 +24,7 @@
#include "Range2d.h"
#include "rect.h" // for inlines
#include "Font.h" // for visibility of font add_ref/drop_ref
+//#include "TextFormat_as.h"
#include <vector>
@@ -33,6 +34,7 @@
class DefineEditTextTag;
class TextRecord;
}
+ class TextFormat_as;
}
namespace gnash {
@@ -450,12 +452,12 @@
void setAlignment(TextAlignment h);
- boost::uint16_t getLeading() const
+ boost::int16_t getLeading() const
{
return _leading;
}
- void setLeading(boost::uint16_t h);
+ void setLeading(boost::int16_t h);
bool getUnderlined() const
{
@@ -484,6 +486,12 @@
void setTarget(std::string target);
void setDisplay(TextFormatDisplay display);
+ TextFormat_as* getTextFormat() const
+ {
+ return _textFormat;
+ }
+ void setTextFormat(TextFormat_as tf);
+
const rect& getTextBoundingBox() const
{
return m_text_bounding_box;
@@ -619,6 +627,8 @@
/// easier.
std::wstring _text;
+ TextFormat_as* _textFormat;
+
/// This flag will be true as soon as the TextField
/// is assigned a text value. Only way to be false is
/// when definition has the hasText flag set to false
@@ -638,7 +648,7 @@
TextFormatDisplay _display;
std::vector<int> _tabStops;
- boost::uint16_t _leading;
+ boost::int16_t _leading;
TextAlignment _alignment;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11340: Case-insensitive HTML parsing.,
Bob Naugle <=