diff options
Diffstat (limited to 'libs/litehtml/containers/haiku/container_haiku.cpp')
-rw-r--r-- | libs/litehtml/containers/haiku/container_haiku.cpp | 568 |
1 files changed, 568 insertions, 0 deletions
diff --git a/libs/litehtml/containers/haiku/container_haiku.cpp b/libs/litehtml/containers/haiku/container_haiku.cpp new file mode 100644 index 0000000000..7c49f22b6f --- /dev/null +++ b/libs/litehtml/containers/haiku/container_haiku.cpp @@ -0,0 +1,568 @@ +/* + * Copyright 2019-2020 Haiku Inc. + * All rights reserved. Distributed under the terms of the BSD 3-clause license. + * Constributors + * 2019-2020 Adam Fowler <adamfowleruk@gmail.com> + */ +#include "container_haiku.h" + +#include <string> +#include <iostream> +#include <fstream> +#include <streambuf> +#include <map> + +#include <Bitmap.h> +#include <String.h> +#include <Entry.h> +#include <Path.h> +#include <TranslationUtils.h> + +LiteHtmlView::LiteHtmlView(BRect frame, const char *name) + : BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW), + fContext(NULL), + m_html(NULL), + m_images(), + m_base_url(), + m_url() +{ + + BRect bounds(Bounds()); + BPoint topLeft = bounds.LeftTop(); + std::cout << "Initial bounds: topLeft x: " << +topLeft.x << ", y: " + << +topLeft.y << ", width: " << +bounds.Width() << ", height: " + << +bounds.Height() << std::endl; + + SetDrawingMode(B_OP_OVER); + SetFont(be_plain_font); + + //FillRect(bounds,B_SOLID_LOW); + + //SetLowColor(B_DOCUMENT_PANEL_COLOR); + //FillRect(rect); +} + +LiteHtmlView::~LiteHtmlView() +{ +} + +void +LiteHtmlView::SetContext(litehtml::context* ctx) +{ + fContext = ctx; +} + +void +LiteHtmlView::RenderFile(const char* localFilePath) +{ + std::cout << "RenderFile" << std::endl; + //BUrlRequest req; + // assume a local file for now, that is HTML + std::ifstream t(localFilePath); + std::string html((std::istreambuf_iterator<char>(t)), + std::istreambuf_iterator<char>()); + + //std::cout << "HTML output:-" << std::endl << html << std::endl; + + // Get parent folder for the base url + std::cout << "Loaded from file: " << localFilePath << std::endl; + BPath htmlPath(localFilePath); + BPath dirPath; + htmlPath.GetParent(&dirPath); + std::cout << "parent path: " << dirPath.Path() << std::endl; + set_base_url(dirPath.Path()); + //std::cout << " base url now:" << m_base_url << std::endl; + + RenderHTML(html); +} + +void +LiteHtmlView::RenderHTML(const std::string& htmlText) +{ + std::cout << "RenderHTML" << std::endl; + + // now use this string + m_html = litehtml::document::createFromString( + htmlText.c_str(), this, fContext); + if (m_html) + { + std::cout << "Successfully read html" << std::endl; + // success + // post-parse render operations, if required. + Invalidate(); + } else { + std::cout << "Failed to read html" << std::endl; + } + // always fire the rendering complete message + std::cout << "Sending html rendered message: " << M_HTML_RENDERED << std::endl; +} + +void +LiteHtmlView::Draw(BRect b) +{ + std::cout << "DRAW CALLED" << std::endl; + + BRect bounds(Bounds()); + FillRect(bounds,B_SOLID_LOW); + + // b only part of the window, but we need to draw the whole lot + + if (NULL != m_html) { + BPoint leftTop = bounds.LeftTop(); + litehtml::position clip(leftTop.x,leftTop.y, + bounds.Width(),bounds.Height()); + m_html->render(bounds.Width()); + m_html->draw((litehtml::uint_ptr) this,0,0,&clip); + } + SendNotices(M_HTML_RENDERED,new BMessage(M_HTML_RENDERED)); +} + +void +LiteHtmlView::GetPreferredSize(float* width,float* height) +{ + if (NULL == m_html) + { + BRect bounds(Bounds()); + *width = bounds.Width(); + *height = bounds.Height(); + } else { + *width = m_html->width(); + *height = m_html->height(); + } +} + +litehtml::uint_ptr +LiteHtmlView::create_font( const litehtml::tchar_t* faceName, int size, + int weight, litehtml::font_style italic, unsigned int decoration, + litehtml::font_metrics* fm ) +{ + //std::cout << "create_font" << std::endl; + litehtml::string_vector fonts; + litehtml::split_string(faceName, fonts, ","); + litehtml::trim(fonts[0]); + + uint16 face = B_REGULAR_FACE; // default + if (italic == litehtml::font_style_italic) + { + face |= B_ITALIC_FACE; + } + if (decoration & litehtml::font_decoration_underline) + { + face |= B_UNDERSCORE_FACE; + } + if (decoration & litehtml::font_decoration_linethrough) + { + face |= B_STRIKEOUT_FACE; + } + // Note: LIGHT, HEAVY, CONDENSED not supported in BeOS R5 +#ifdef __HAIKU__ + if(weight >= 0 && weight < 150) face |= B_LIGHT_FACE; + else if(weight >= 150 && weight < 250) face |= B_LIGHT_FACE; + else if(weight >= 250 && weight < 350) face |= B_LIGHT_FACE; + //else if(weight >= 350 && weight < 450) face |= B_REGULAR_FACE; + //else if(weight >= 450 && weight < 550) face |= B_REGULAR_FACE; + else if(weight >= 550 && weight < 650) face |= B_CONDENSED_FACE; +#else + else if(weight >= 550 && weight < 650) face |= B_BOLD_FACE; +#endif + else if(weight >= 650 && weight < 750) face |= B_BOLD_FACE; +#ifndef __HAIKU__ + else if(weight >= 750 && weight < 850) face |= B_BOLD_FACE; + else if(weight >= 950) face |= B_BOLD_FACE; +#else + else if(weight >= 750 && weight < 850) face |= B_HEAVY_FACE; + else if(weight >= 950) face |= B_HEAVY_FACE; +#endif + + BFont* tempFont = new BFont(); + bool found = false; + for(litehtml::string_vector::iterator i = fonts.begin(); + i != fonts.end(); i++) + { + if (B_OK == tempFont->SetFamilyAndFace(i->c_str(),face)) + { + found = true; + break; + } + } + + if (!found) + { + // default to the Be plain font + tempFont = new BFont(be_plain_font); + if (weight >= 550) + { + tempFont = new BFont(be_bold_font); + } + tempFont->SetFace(face); // chooses closest + } + + tempFont->SetSize(size); + + font_height hgt; + tempFont->GetHeight(&hgt); + fm->ascent = hgt.ascent; + fm->descent = hgt.descent; + fm->height = (int) (hgt.ascent + hgt.descent); + fm->x_height = (int) hgt.leading; + + return (litehtml::uint_ptr) tempFont; +} + +void +LiteHtmlView::delete_font( litehtml::uint_ptr hFont ) +{ + std::cout << "delete_font" << std::endl; +} + +int +LiteHtmlView::text_width( const litehtml::tchar_t* text, + litehtml::uint_ptr hFont ) +{ + //std::cout << "text_width" << std::endl; + BFont* fnt = (BFont*)hFont; + int width = fnt->StringWidth(text); + //std::cout << " Width: " << +width << std::endl; + return width; +} + +void +LiteHtmlView::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, + litehtml::uint_ptr hFont, litehtml::web_color color, + const litehtml::position& pos ) +{ + //std::cout << "draw_text" << std::endl; + if (!text) return; + if (0 == strlen(text)) return; + BFont* fnt = (BFont*)hFont; + + //std::cout << " left: " << +pos.left() << ", top: " << +pos.top() << std::endl; + //std::cout << " RGBA: " << +color.red << "," << +color.green << "," << +color.blue << "," << +color.alpha << std::endl; + //std::cout << " Font size: " << +fnt->Size() << std::endl; + //std::cout << " Text: " << text << std::endl; + BRect bounds(Bounds()); + + //FillRect(bounds,B_SOLID_LOW); + + BPoint leftTop = bounds.LeftTop(); + //std::cout << " Bounds left: " << +leftTop.x << ", top: " << +leftTop.y << ", Width: " << +bounds.Width() << ", Height: " << +bounds.Height() << std::endl; + + font_height fh; + fnt->GetHeight(&fh); + int baseline = fh.ascent + fh.descent;// + 10; + int leftbase = 0; //10; + MovePenTo(pos.left() + leftbase,pos.top() + baseline);//leftTop.x,leftTop.y); + SetFont(fnt); + //SetFont(be_plain_font); + rgb_color clr = ui_color(B_DOCUMENT_TEXT_COLOR); + /* + rgb_color clr; + clr.blue = 40; + clr.red = 40; + clr.green = 40; + */ + + clr.red = color.red; + clr.green = color.green; + clr.blue = color.blue; + clr.alpha = color.alpha; + + //std::cout << " Final RGBA: " << +clr.red << "," << +clr.green << "," << +clr.blue << "," << +clr.alpha << std::endl; + SetHighColor(clr); + SetLowColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + BString mystr(""); + //mystr << "text: "; + mystr << text; + DrawString(mystr); +} + +int +LiteHtmlView::pt_to_px( int pt ) +{ + std::cout << "pt_to_px" << std::endl; + return (int) ((double) pt * 1.3333333333); +} + +int +LiteHtmlView::get_default_font_size() const +{ + //std::cout << "get_default_font_size" << std::endl; + return 12; +} + +const litehtml::tchar_t* +LiteHtmlView::get_default_font_name() const +{ + //std::cout << "get_default_font_name" << std::endl; + font_family fam; + font_style style; + be_plain_font->GetFamilyAndStyle(&fam,&style); + char* cp = strdup(fam); + return (litehtml::tchar_t*)cp; +} + +void +LiteHtmlView::draw_list_marker( litehtml::uint_ptr hdc, + const litehtml::list_marker& marker ) +{ + std::cout << "draw_list_marker" << std::endl; + if (!marker.image.empty()) + { + std::cout << " image marker" << std::endl; + } +} + +void +LiteHtmlView::load_image( const litehtml::tchar_t* src, + const litehtml::tchar_t* baseurl, bool redraw_on_ready ) +{ + std::cout << "load_image" << std::endl; + + std::string url; + make_url(src, baseurl, url); + if(m_images.find(url.c_str()) == m_images.end()) + { + BEntry entry(url.c_str(), true); + if (entry.Exists()) { + std::cout << " Loading bitmap from file" << std::endl; + BBitmap* img = BTranslationUtils::GetBitmap(url.c_str()); + m_images[url] = img; + } + } +} + +void +LiteHtmlView::make_url(const litehtml::tchar_t* url, + const litehtml::tchar_t* basepath, litehtml::tstring& out) +{ + std::cout << "make_url" << std::endl; + std::cout << " url: " << url << std::endl; + if(!basepath || (basepath && !basepath[0])) + { + if(!m_base_url.empty()) + { + //out = urljoin(m_base_url, std::string(url)); + std::string ns(m_base_url); + ns += "/"; + ns += url; + out = ns; + } else + { + out = url; + } + } else + { + std::cout << " basepath: " << basepath << std::endl; + //out = urljoin(std::string(basepath), std::string(url)); + std::string ns(basepath); + ns += "/"; + ns += url; + out = ns; + } + std::cout << " Output url: " << out << std::endl; +} + +void +LiteHtmlView::set_base_url(const litehtml::tchar_t* base_url) +{ + std::cout << "set_base_url" << std::endl; +/* + if(base_url) + { + m_base_url = urljoin(m_url, std::string(base_url)); + } else + { + */ + m_base_url = base_url; + std::cout << " base url set to: " << m_base_url << std::endl; + //} +} + + +void +LiteHtmlView::get_image_size( const litehtml::tchar_t* src, + const litehtml::tchar_t* baseurl, litehtml::size& sz ) +{ + std::cout << "get_image_size" << std::endl; + std::string url; + make_url(src,NULL,url); + const auto& miter(m_images.find(url.c_str())); + if (m_images.end() != miter) + { + BBitmap* img = (BBitmap*)miter->second; + BRect size = img->Bounds(); + sz.width = size.Width(); + sz.height = size.Height(); + std::cout << " width: " << +sz.width << ", height: " << +sz.height << std::endl; + } +} + +void +LiteHtmlView::draw_image( litehtml::uint_ptr hdc, const litehtml::tchar_t* src, + const litehtml::tchar_t* baseurl, const litehtml::position& pos ) +{ + std::string url; + make_url(src, baseurl, url); + const auto& img = m_images.find(url.c_str()); + if(img != m_images.end()) + { + if(img->second) + { + DrawBitmap(img->second,BPoint(pos.x,pos.y)); // TODO support scaling + //draw_txdib(cr, img->second.get(), pos.x, pos.y, pos.width, pos.height); + } + } +} + +void +LiteHtmlView::draw_background( litehtml::uint_ptr hdc, + const litehtml::background_paint& bg ) +{ + std::cout << "draw_background" << std::endl; + if (0 < bg.image.length()) + { + std::cout << " background includes an image!" << std::endl; + draw_image(hdc,bg.image.c_str(),m_base_url.c_str(),litehtml::position(bg.position_x,bg.position_y,bg.image_size.width,bg.image_size.height)); + } +} + +void +LiteHtmlView::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) +{ + std::cout << "draw_borders" << std::endl; + int bdr_top = 0; + int bdr_bottom = 0; + int bdr_left = 0; + int bdr_right = 0; + + //std::cout << " uint ptr: " << +hdc << std::endl; + //std::cout << " this ptr: " << +this << std::endl; + + if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) + { + bdr_top = (int) borders.top.width; + std::cout << " Border top: " << bdr_right << std::endl; + } + if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) + { + bdr_bottom = (int) borders.bottom.width; + std::cout << " Border bottom: " << bdr_right << std::endl; + } + if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) + { + bdr_left = (int) borders.left.width; + std::cout << " Border left: " << bdr_right << std::endl; + } + if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) + { + bdr_right = (int) borders.right.width; + std::cout << " Border right: " << bdr_right << std::endl; + } + + + if (bdr_bottom) + { + // draw rectangle for now - no check for radius + StrokeRect( + BRect( + BPoint(draw_pos.left(), draw_pos.bottom()), + BPoint(draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom) + ) + ); + } +} + +void +LiteHtmlView::transform_text(litehtml::tstring& text, litehtml::text_transform tt) +{ + std::cout << "transform_text" << std::endl; +} + +void +LiteHtmlView::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius ) +{ + std::cout << "set_clip" << std::endl; +} + +void +LiteHtmlView::del_clip() +{ + std::cout << "del_clip" << std::endl; +} + + + +std::shared_ptr<litehtml::element> +LiteHtmlView::create_element(const litehtml::tchar_t *tag_name, + const litehtml::string_map &attributes, + const std::shared_ptr<litehtml::document> &doc) +{ + //std::cout << "create_element" << std::endl; + return 0; +} + +void +LiteHtmlView::get_media_features(litehtml::media_features& media) const +{ + std::cout << "get_media_features" << std::endl; + litehtml::position client; + get_client_rect(client); + media.type = litehtml::media_type_screen; + media.width = client.width; + media.height = client.height; + BRect bounds(Bounds()); + media.device_width = bounds.Width(); + media.device_height = bounds.Height(); + media.color = 8; + media.monochrome = 0; + media.color_index = 256; + media.resolution = 96; +} + +void +LiteHtmlView::link(const std::shared_ptr<litehtml::document> &ptr, const litehtml::element::ptr& el) +{ + std::cout << "link" << std::endl; +} + +void +LiteHtmlView::set_caption(const char* caption) +{ + std::cout << "set_caption" << std::endl; +} + +void +LiteHtmlView::get_client_rect(litehtml::position& client) const +{ + //std::cout << "get_client_rect" << std::endl; + BRect bounds(Bounds()); + BPoint leftTop = bounds.LeftTop(); + client.width = bounds.Width(); + client.height = bounds.Height(); + client.x = leftTop.x; + client.y = leftTop.y; +} + +void +LiteHtmlView::on_anchor_click(const char* base, const litehtml::element::ptr& anchor) +{ + std::cout << "on_anchor_click" << std::endl; +} + +void +LiteHtmlView::set_cursor(const char* cursor) +{ + std::cout << "set_cursor" << std::endl; +} + +void +LiteHtmlView::import_css(litehtml::tstring& s1, const litehtml::tstring& s2, litehtml::tstring& s3) +{ + std::cout << "import_css" << std::endl; +} + +void +LiteHtmlView::get_language(litehtml::tstring& s1, litehtml::tstring& s2) const +{ + std::cout << "get_language" << std::endl; +} |