Kaydet (Commit) a59dbc9e authored tarafından Özgür Alp's avatar Özgür Alp

Last changes for build

üst 7b8b6613
{
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"ostream": "cpp",
"ranges": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"variant": "cpp"
}
}
\ No newline at end of file
## Kod Yapısı
1. Skeleton
- HTML , JS ve CSS ile oluşturulan uygulamanın doğal C++ olarak toplanacağı yer , oluşturualacak uygulama iskeleti.
- C++ ile yazılmıştır. Include, GL için gerekli ekrana basılacak CSS yerleşim ağacının vertex bilgilerini bağlayan, bu objelerin
HTML'deki fonksiyon eşleştirmesine göre Transpiler katmanından gelen hangi olay yönetimiyle eşleşeceğini belirleyen
GL soyutlayıcı fonksiyonları/sınıfları içerir.
1. PCodegenWrapper.hh
- Graphics'deki tasarım hesaplayıcısının çıktılarındaki bilgiler, bu wrapper'daki çizim sınıfından objelerdir.
2. PGLFWWrapper.hh
- GLFW'nin pencere, olay yönetimlerini soyutlar.
3. PShaderWrapper.hh
- Ekran kartına iletilecek shaderların (Vertex , Fragment) g/ç işlemleri yapılır.
4. PTextWrapper.hh
- Belirtilen metnin belirtilen fontta ekrana basılmasını sağlar.
5. PTranspilerWrapper.hh
- Javascript Transpiler'ının çıktısının iletişmesi için bazı yardımcılar.
6. PVertexObjectsWrapper.hh
- VBO,VAO işlemleri yapılır.
- Libraries , GLFW (Çapraz-platform pencere yönetimi için ), glm( GL Matematiği için), freetype (Font hesaplamaları için)
başlık dosyalarını içerir.
- Source, Etc/'deki GLMain.cc şablonuna göre bağlayıcı tarafından oluşturulacak son kodun yerleştirileceği yerdir.
- CMakeLists , GLMain dahil son proje
2. Graphics
- Rust ile yazılmıştır. /src altında tüm işlemler paketlenmiş kitaplık oluşturmak üzere yapılır , /main bu kitaplığı alır.
1. Codegen.rs
- C++ GL Çağrılarını oluşturur. (PCodegenWrapper uyarınca)
2. Hypertext.rs
- HTML Parçalayıcısı.
3. LayoutTree.rs
- Yerleşim Ağacı. Stil ağacından sonra , 'stil özelliklerindeki padding,margin,border verieri bu objeyi nereye konumlandırır' amacıyla çalışır , sonucu RenderableCommand'a iletir.
4. ObjectModel.rs
- HTML DOM implementasyonu, HTML için bir sözdizimi ağacı yapısıdır.
5. RenderableCommand.rs
- Codegen'e gönderilecek- hesaplanmış içerikler sonucu- komutları üretir.
6. Style.rs
- CSS dosyasının içerdiği özelliklerin ağaçlandırılması (Seçiciler, özellikler ,değerler, değer birimleri).
7. StyleTree.rs
- HTML + CSS ile birlikte parçalanmış ağaçların ilk birleştirildiği, her elementin özgül özelliklerinin kararkaştırıldığı
yer.
8. StylesheetParser.rs
- CSS Parçalayıcısı.
- Rustc derleyicisi yada rustup araç takımı gerektirir. Oluşan uygulama 2 adet parametre alır,
html ve css dosya yollarını belirtirsiniz. Çıktı Output.csv'dir.
3. Transpiler
4. Libraries, jast adlı hafif bir açık kaynak Javascript parçalayıcısı içerir. Source klasöründeki ast-dump dosyaları C++ kod
üretmek için sözdizimi ağacını dolaşır.
- Oluşan transpiler, kodu STDIN'den alır. Transpiler'ın çıktısının daha rahat lint edilebilir ve derleyiciler tarafından
tokenize edilebilir olması için Etc'de son aşamada kullanılacak bağlayıcı temizlemeleri yapar , istatistikleri çıkarır.
4. Etc
1. Pertev.py , ./Build.sh ile /Etc/Output'a aktarılan çalıştırılabilir dosyalarla test.html,css,js dosyalarını birleştirir. Çıktıları işler , GLMain.cc.template 'de belirtilen şablona uygun yerlere yerleştirir. GLMain.cc çıktısını taşır, Skeleton'un
yapı işlerini başlatır.
\ No newline at end of file
## Yapı Gerejsinimleri
C++ Derleyici Seti : Clang++11 önerilir
```bash
sudo apt install clang
```
Rust Seti : Rustup önerilir.
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
X11-OpenGL Geliştirme Dosyaları :
```bash
sudo apt-get install freeglut3 freeglut3-dev libglu1-mesa libglu1-mesa-dev libgl1-mesa-glx libgl1-mesa-dev
```
python3
cmake
```bash
sudo apt-get install cmake
```
## Otomatik Yapılandırma
./Build.sh , ardından Etc/Pertev.py size çalıştırılabilir son çıktıyı oluşturur.
\ No newline at end of file
document->rectangles["orange box"]->onClick = e ;
document->rectangles["red box"]->onKeyDown = kdwn_red ;
......@@ -39,7 +39,7 @@ int main(int argc, char **argv)
// document.rectangles["btn1"] = new Rectangle("btn1", 0.5f, 0.5f, 0.5f, 0.6f, 0.1f, 0.2f, 1.0f);
//document.rectangles["btn1"]->onKeyDown = OnButtonDown;
document->rectangles.insert(std::pair<std::string , Rectangle*> ("ide", new Rectangle("blue box", -0.9902344f, 0.8828125f, 0.104166664f, 0.6f, 0.0f, 0.0f, 1.0f)));
//document->rectangles.insert(std::pair<std::string , Rectangle*> ("ide", new Rectangle("blue box", -0.9902344f, 0.8828125f, 0.104166664f, 0.6f, 0.0f, 0.0f, 1.0f)));
$defrect
......@@ -56,12 +56,12 @@ int main(int argc, char **argv)
r.second->Render();
// Run all allkeydowns.
for (auto key : window.KeyMap)
for (int keyn = 0 ; keyn < 512 ; keyn++)
{
if (key == true)
if (window.KeyMap[keyn] == true)
{
for (auto r : document->rectangles)
r.second->onKeyDown(std::make_shared<Object>((int)key));
r.second->onKeyDown(std::make_shared<Object>(keyn));
}
}
if (window.ButtonMap[GLFW_MOUSE_BUTTON_RIGHT])
......
document->rectangles.insert(std::pair<std::string , Rectangle*>(blue box , new Rectangle("blue box" , -0.9902344, 0.8828125, 0.104166664, 0.6, 0, 0, 1)));
document->rectangles.insert(std::pair<std::string , Rectangle*>(orange box , new Rectangle("orange box" , -0.3707031, 0.8828125, 0.104166664, 0.6, 1, 0.64705884, 0)));
document->rectangles.insert(std::pair<std::string , Rectangle*>(black box , new Rectangle("black box" , 0.24882817, 0.8828125, 0.104166664, 0.6, 0, 0, 0)));
document->rectangles.insert(std::pair<std::string , Rectangle*>(green box , new Rectangle("green box" , -0.9902344, 0.7526041, 0.104166664, 0.6, 0.18039216, 0.74509805, 0.101960786)));
document->rectangles.insert(std::pair<std::string , Rectangle*>(red box , new Rectangle("red box" , -0.3707031, 0.7526041, 0.104166664, 0.6, 0.8392157, 0.09019608, 0.09019608)));
document->rectangles.insert(std::pair<std::string , Rectangle*>(bronze box , new Rectangle("bronze box" , 0.24882817, 0.7526041, 0.104166664, 0.6, 0.7607843, 0.41960785, 0.07450981)));
document->rectangles.insert(std::pair<std::string , Rectangle*>(orangered box , new Rectangle("orangered box" , -0.9902344, 0.6223958, 0.104166664, 0.6, 1, 0.27058825, 0)));
document->rectangles.insert(std::pair<std::string , Rectangle*>("red box" , new Rectangle("red box" , -0.990234f, 0.882812f, 0.104167f, 0.600000f, 0.839216f, 0.0901961f, 0.0901961f)));
# Test script to check paranthesis in call exps. generated by transpiler.
# pertev
import os
import sys
......
......@@ -14,21 +14,27 @@ import os
import subprocess
import re
from string import Template
from pathlib import Path
def Generate(esFile):
def generate_transpiled_output(esFile):
''' Run transpiler '''
# with open('Output.cc.dat', 'w') as f:
cmd = "cat {0}/{1} | ./'Output/pertevtranspiler' > Output.cc.dat ".format(
os.getcwd(), esFile)
# ps = subprocess.Popen(cmd, stdout=subprocess.PIPE)
# output = subprocess.check_output(("./'Output/main'"), stdin=ps.stdout , stdout=f)
# ps.wait()
os.system(cmd)
def generate_graphics(htmlfile , cssfile):
''' Run renderer '''
cmd = "./'Output/main' {0} {1} ".format(
htmlfile , cssfile)
os.system(cmd)
def CleanComments(text):
''' Clean traverse log '''
def replacer(match):
s = match.group(0)
if s.startswith('/'):
......@@ -42,8 +48,6 @@ def CleanComments(text):
return re.sub(pattern, replacer, text)
def tail(f, _buffer=4098):
""" Get codegen log -memory efficient-platform independence!-"""
......@@ -64,9 +68,11 @@ def tail(f, _buffer=4098):
return lines_found[-6:]
Generate('test.js')
# Generate
generate_transpiled_output('test.js')
generate_graphics('test.html' , 'test.css')
# Apply
with open('Output.cc.dat', 'r') as file:
for statistics in tail(file):
print(statistics)
......@@ -91,9 +97,9 @@ print('Output cleaned.')
def templated(js_cleaned , initial_rect , bind_funcmap , template):
# js_cleaned_v , initial_rect_v , bind_funcmap_v , template_v
''' Append outputs to GL Wrappers '''
#todo: Simple but very expensive function... so .. memory-maping??
#TODO: Simple but very expensive function... memory-maping??
with open(js_cleaned, 'r') as f:
js_cleaned_v = f.read()
with open(initial_rect, 'r') as f2:
......@@ -103,11 +109,14 @@ def templated(js_cleaned , initial_rect , bind_funcmap , template):
with open(template, 'r+') as f4:
template_v = f4.read()
template_v_tmp = Template(template_v)
template_output = (template_v_tmp.substitute(funcinit= js_cleaned_v , defrect = initial_rect_v , setfunc= bind_funcmap))
with open('GLMain.cc' , 'w') as f5:
f5.write(template_output)
os.replace(f"{os.getcwd()}/GLMain.cc", f"{Path().absolute().parent}/Skeleton/Source/GLMain.cc")
os.chdir(f"{Path().absolute().parent}/Skeleton/Source")
os.system('cmake .. && make ')
def run_graphic_rendering (html , css ):
cmd = "./'Output/main' {}/{} {}/{} ".format(os.getcwd(), html , os.getcwd() ,css)
......
......@@ -5,13 +5,7 @@
</head>
<body>
<div class="blue box">This is a blue box</div>
<div class="orange box" onclick="e"></div>
<div class="black box"></div>
<div class="green box"></div>
<div class="red box"></div>
<div class="bronze box"></div>
<p class="orangered box"></p>
<div class="red box" onKeyDown="kdwn_red"></div>
</body>
</html>
\ No newline at end of file
function run(e)
{
var but = document.getElementById('btn1');
but.translate(but.getPositionX() + 0.01 , but.getPositionX());
function kdwn_red(e) {
var but = document.getElementById('red box');
if (e == 262) { // Sağ
but.translate(but.getPositionX() + 0.01, but.getPositionY());
}
if (e == 263) {// Sol
but.translate(but.getPositionX() - 0.01, but.getPositionY());
}
if (e == 264) { // Alt
but.translate(but.getPositionX(), but.getPositionY() - 0.01);
}
if (e == 265) { // Üst
but.translate(but.getPositionX(), but.getPositionY() + 0.01);
}
return 1;
}
\ No newline at end of file
}
......@@ -10,6 +10,40 @@ use LayoutTree;
const SCREEN_WIDTH: usize = 1024;
const SCREEN_HEIGHT: usize = 768;
fn meh(float: f32, precision: usize) -> String {
// compute absolute value
let a = float.abs();
// if abs value is greater than 1, then precision becomes less than "standard"
let precision = if a >= 1. {
// reduce by number of digits, minimum 0
let n = (1. + a.log10().floor()) as usize;
if n <= precision {
precision - n
} else {
0
}
// if precision is less than 1 (but non-zero), then precision becomes greater than "standard"
} else if a > 0. {
// increase number of digits
let n = -(1. + a.log10().floor()) as usize;
precision + n
// special case for 0
} else {
0
};
if float == 0_f32 {
format!("0.0")
}
else{
// format with the given computed precision
format!("{0:.1$}", float, precision) }
}
/// DisplayCommand, render edilme amacıyla pozisyonlama verilerini dönüştürür.
/// Pozisyonlar, CodegenWrapper'dan document-> işaretçisine, html-id'sine göre atanır.
fn render_commands(command_list: &[DisplayCommand]) -> Result<(), Box<dyn Error>> {
let mut rendered_file = File::create("Output.csv")?;
......@@ -18,15 +52,15 @@ fn render_commands(command_list: &[DisplayCommand]) -> Result<(), Box<dyn Error>
DisplayCommand::SolidRectangle(ref ident , ref color, ref rect) => {
let (x, y, h, w) = transform_rectangle(rect);
let out = [
x.to_string(),
y.to_string(),
h.to_string(),
w.to_string(),
color.r.to_string(),
color.g.to_string(),
color.b.to_string(),
meh(x,6) + "f",
meh(y,6) + "f",
meh(h,6) + "f",
meh(w,6) + "f",
meh(color.r,6) + "f",
meh(color.g,6) + "f",
meh(color.b ,6) + "f",
];
writeln!(rendered_file, "document->rectangles.insert(std::pair<std::string , Rectangle*>({} , new Rectangle(\"{}\" , {})));", ident, ident , out.join(", "));
writeln!(rendered_file, "document->rectangles.insert(std::pair<std::string , Rectangle*>(\"{}\" , new Rectangle(\"{}\" , {})));", ident, ident , out.join(", "));
// document->rectangles.insert(std::pair<std::string , Rectangle*> ("ide", new Rectangle("blue box", -0.9902344f, 0.8828125f, 0.104166664f, 0.6f, 0.0f, 0.0f, 1.0f)));
}
......@@ -37,7 +71,7 @@ fn render_commands(command_list: &[DisplayCommand]) -> Result<(), Box<dyn Error>
Ok(())
}
/// f32 olarak alınan değerleri (ki bu doğrudan bir vertex verisidir) , temiz değerlere çevirir.
fn transform_rectangle(rect: &LayoutTree::Rectangle) -> (f32, f32, f32, f32) {
let w = rect.width / SCREEN_WIDTH as f32 * 2.0;
let h = rect.height / SCREEN_HEIGHT as f32 * 2.0;
......@@ -47,6 +81,7 @@ fn transform_rectangle(rect: &LayoutTree::Rectangle) -> (f32, f32, f32, f32) {
(x, y, h, w)
}
// Komutları çekecek ana Codegen fonksiyonu.
pub fn render_loop(command_list: &[DisplayCommand]) {
if let Err(e) = render_commands(command_list) {
eprintln!("{}", e);
......
......@@ -3,13 +3,15 @@ use ObjectModel::{AttrMap, ElementData, Node, NodeType};
use std::iter::Peekable;
use std::str::Chars;
/// Parçalayıcı yapısı , burası implemente edilmiştir : Rekürsif parçalama, karakter katarı üzerinde oynama.
pub struct HtmlParser<'a> {
chars: Peekable<Chars<'a>>,
node_q: Vec<String>,
}
impl<'a> HtmlParser<'a> {
/// Tüm html kaynağını alarak parçalayıcı sınıfını türetir.
pub fn new(full_html: &str) -> HtmlParser {
HtmlParser {
chars: full_html.chars().peekable(),
......@@ -17,6 +19,8 @@ impl<'a> HtmlParser<'a> {
}
}
/// Parçalamanın ana fonksiyonu , özyinelemeli tasarım deseni ile standart bir parçalayıcı.
/// Yorumlar ve elemente ait anahtarların değerlerinin parçalanması diğer fonksiyonlara yönlendirilir.
pub fn parse_nodes(&mut self) -> Vec<Node> {
let mut nodes = Vec::new();
......@@ -62,7 +66,7 @@ impl<'a> HtmlParser<'a> {
}
nodes
}
/// DOM üzerinde bir node'u oluşturmak için parçalayıcı fonksiyonları koşturur.
fn parse_node(&mut self) -> Node {
let tagname = self.consume_while(is_valid_tag_name);
let attributes = self.parse_attributes();
......@@ -72,6 +76,7 @@ impl<'a> HtmlParser<'a> {
Node::new(NodeType::Element(elem), children)
}
/// Etiketlerarası metin biçemini çeker.
fn parse_text_node(&mut self) -> Node {
let mut text_content = String::new();
......@@ -86,6 +91,8 @@ impl<'a> HtmlParser<'a> {
Node::new(NodeType::Text(text_content), Vec::new())
}
/// HTML yorum satırları için gerekli parçalamayı yapar.
/// Örn : <!-- -->
fn parse_comment_node(&mut self) -> Node {
let mut comment_content = String::new();
......@@ -181,6 +188,7 @@ impl<'a> HtmlParser<'a> {
Node::new(NodeType::Comment(comment_content), Vec::new())
}
/// Element anahtarlarını çeker. Örn : <elem attr="value">
fn parse_attributes(&mut self) -> AttrMap {
let mut attributes = AttrMap::new();
......@@ -205,7 +213,7 @@ impl<'a> HtmlParser<'a> {
attributes
}
/// Tırnak işaretleri arasına alınmış anahtar değerlerini : attr=value , alır.
fn parse_attr_value(&mut self) -> String {
self.consume_while(char::is_whitespace);
......@@ -223,6 +231,8 @@ impl<'a> HtmlParser<'a> {
}
/// Lambda fonksiyonun koşulu sağlandıkça sonuca gerekli karakterleri ekler,
/// diğer türlü ilerlemeyi sürdürür ve sonucu String türünden döndürür.
fn consume_while<F>(&mut self, condition: F) -> String
where
F: Fn(char) -> bool,
......
......@@ -3,6 +3,9 @@ use std::fmt;
use Style::{Unit, Value};
use StyleTree::{Display, StyledNode};
/// Dimentions değeri , w-h cinsinden yerleşimi belirler.
/// Type , css kutusunun yerleşim türüdür.
/// Styled-node , stil özellikleriyle oluşturulmuş DOM.
#[derive(Clone)]
pub struct LayoutBox<'a> {
pub dimensions: Dimensions,
......@@ -10,6 +13,7 @@ pub struct LayoutBox<'a> {
pub styled_node: &'a StyledNode<'a>,
pub children: Vec<LayoutBox<'a>>,
}
#[derive(Clone, Copy, Default)]
pub struct Dimensions {
pub content: Rectangle,
......@@ -63,7 +67,7 @@ impl<'a> LayoutBox<'a> {
BoxType::Anonymous => {}
}
}
fn layout_inline_block(&mut self, b_box: Dimensions) {
self.calculate_inline_width(b_box);
self.calculate_inline_position(b_box);
......
......@@ -7,12 +7,14 @@ use std::io::Write;
use std::fs::OpenOptions;
/// DOM Modeli , Kendi türünden alt çocukları (bağlı) ve bir özgül tür belirteci.
#[derive(PartialEq, Eq)]
pub struct Node {
pub children: Vec<Node>,
pub node_type: NodeType,
}
/// Bir node, ya metin ya bir HTML elementi ya da bir yorum satırı belirtebilir.
#[derive(PartialEq, Eq, Clone)]
pub enum NodeType {
Text(String),
......@@ -20,6 +22,7 @@ pub enum NodeType {
Comment(String),
}
/// Element tutan bir DOM node'u, tag : attr-value , attr-value olarak tutulmalıdır.
#[derive(PartialEq, Eq, Clone)]
pub struct ElementData {
pub tag_name: String,
......@@ -34,6 +37,8 @@ impl ElementData {
}
}
/// Identifier'ın alınması, son aşamada fonksiyon haritasıyla
/// doğru bir biçimde eşleştirmek için yapılır.
pub fn get_id(&self) -> Option<&String> {
self.attributes.get("id")
}
......@@ -55,6 +60,7 @@ impl Node {
children,
}
}
/// Element verilerini al.
pub fn GetElementData(&self) -> Option<ElementData> {
if let NodeType::Element(s) = self.node_type.clone() {
Option::from(s)
......@@ -108,7 +114,7 @@ pub fn pretty_print(n: &Node, indent_size: usize) {
_ => {}
}
}
/// Fonksiyon haritasını belirtilen ID'lere göre oluştur.
pub fn writeffmap(elemd: ElementData) -> Result<(), Box<dyn Error>> {
let mut rendered_file = OpenOptions::new()
.write(true)
......@@ -128,7 +134,9 @@ pub fn writeffmap(elemd: ElementData) -> Result<(), Box<dyn Error>> {
id = (*value).clone();
}
if attr == "onclick" {
if attr == "onclick" || attr == "onClick" {
if id == "0" { break; }
onclick = (*value).clone();
writeln!(
rendered_file ,
......@@ -136,7 +144,8 @@ pub fn writeffmap(elemd: ElementData) -> Result<(), Box<dyn Error>> {
id.clone() , onclick.clone()
);
}
if attr == "onhover" {
if attr == "onhover" || attr == "onHover" {
if id == "0" { break; }
onhover = (*value).clone();
writeln!(
rendered_file,
......@@ -144,7 +153,8 @@ pub fn writeffmap(elemd: ElementData) -> Result<(), Box<dyn Error>> {
id.clone(), onhover.clone()
);
}
if attr == "onmousedown" {
if attr == "onkeydown" || attr == "onKeyDown" {
if id == "0" { break; }
onbtndwn = (*value).clone();
writeln!(
rendered_file,
......
......@@ -4,6 +4,7 @@ use std::fmt;
pub type DisplayList = Vec<DisplayCommand>;
/// Ekrana basılacak bir çizim.
pub enum DisplayCommand {
SolidRectangle(String, Color, Rectangle),
}
......@@ -71,8 +72,7 @@ fn render_borders(commands: &mut DisplayList, layout_box: &LayoutBox) {
let border_box = d.border_box();
commands.push(DisplayCommand::SolidRectangle(
identifier.clone(),
color.clone(),
identifier.clone() + "1", color.clone(),
Rectangle {
x: border_box.x,
y: border_box.y,
......@@ -82,7 +82,7 @@ fn render_borders(commands: &mut DisplayList, layout_box: &LayoutBox) {
));
commands.push(DisplayCommand::SolidRectangle(
identifier.clone(),
identifier.clone() + "2",
color.clone(),
Rectangle {
x: border_box.x + border_box.width - d.border.right,
......@@ -93,7 +93,7 @@ fn render_borders(commands: &mut DisplayList, layout_box: &LayoutBox) {
));
commands.push(DisplayCommand::SolidRectangle(
identifier.clone(),
identifier.clone() + "3",
color.clone(),
Rectangle {
x: border_box.x,
......@@ -104,8 +104,7 @@ fn render_borders(commands: &mut DisplayList, layout_box: &LayoutBox) {
));
commands.push(DisplayCommand::SolidRectangle(
identifier.clone(),
color,
identifier.clone() + "4", color,
Rectangle {
x: border_box.x,
y: border_box.y + border_box.height - d.border.bottom,
......
......@@ -116,7 +116,7 @@ impl<'a> CssParser<'a> {
s @ _ => Some(s.to_string()),
}
}
///
fn parse_declarations(&mut self) -> Vec<Declaration> {
let mut declarations = Vec::<Declaration>::new();
......@@ -221,7 +221,7 @@ fn translate_length(value: &str) -> Value {
}
}
/// Neredeyse tüm renk değerlerini destekler. RGB, HEX, BGA, css-tanımları.
fn translate_color(color: &str) -> Color {
if color.starts_with("#") {
if color.len() == 7 {
......