Numworks Epsilon  1.4.1
Graphing Calculator Operating System
layout_engine.cpp
Go to the documentation of this file.
2 #include "layout/string_layout.h"
5 extern "C" {
6 #include<assert.h>
7 }
8 
9 namespace Poincare {
10 
11 ExpressionLayout * LayoutEngine::createInfixLayout(const Expression * expression, PrintFloat::Mode floatDisplayMode, Expression::ComplexFormat complexFormat, const char * operatorName) {
12  assert(floatDisplayMode != PrintFloat::Mode::Default);
14  int numberOfOperands = expression->numberOfOperands();
15  assert(numberOfOperands > 1);
16  ExpressionLayout** children_layouts = new ExpressionLayout * [2*numberOfOperands-1];
17  children_layouts[0] = expression->operand(0)->createLayout();
18  for (int i=1; i<numberOfOperands; i++) {
19  children_layouts[2*i-1] = new StringLayout(operatorName, 1);
20  children_layouts[2*i] = expression->operand(i)->type() == Expression::Type::Opposite ? new ParenthesisLayout(expression->operand(i)->createLayout(floatDisplayMode, complexFormat)) : expression->operand(i)->createLayout(floatDisplayMode, complexFormat);
21  }
22  /* HorizontalLayout holds the children layouts so they do not need to be
23  * deleted here. */
24  ExpressionLayout * layout = new HorizontalLayout(children_layouts, 2*numberOfOperands-1);
25  delete[] children_layouts;
26  return layout;
27 }
28 
29 ExpressionLayout * LayoutEngine::createPrefixLayout(const Expression * expression, PrintFloat::Mode floatDisplayMode, Expression::ComplexFormat complexFormat, const char * operatorName) {
30  assert(floatDisplayMode != PrintFloat::Mode::Default);
32  int numberOfOperands = expression->numberOfOperands();
33  ExpressionLayout * argumentLayouts = nullptr;
34  if (numberOfOperands > 0) {
35  ExpressionLayout ** grandChildrenLayouts = new ExpressionLayout *[2*numberOfOperands-1];
36  int layoutIndex = 0;
37  grandChildrenLayouts[layoutIndex++] = expression->operand(0)->createLayout(floatDisplayMode, complexFormat);
38  for (int i = 1; i < numberOfOperands; i++) {
39  grandChildrenLayouts[layoutIndex++] = new StringLayout(",", 1);
40  grandChildrenLayouts[layoutIndex++] = expression->operand(i)->createLayout(floatDisplayMode, complexFormat);
41  }
42  /* HorizontalLayout holds the grand children layouts so they do not need to
43  * be deleted */
44  argumentLayouts = new HorizontalLayout(grandChildrenLayouts, 2*numberOfOperands-1);
45  delete [] grandChildrenLayouts;
46  }
47  ExpressionLayout * childrenLayouts[2];
48  childrenLayouts[0] = new StringLayout(operatorName, strlen(operatorName));
49  childrenLayouts[1] = new ParenthesisLayout(argumentLayouts);
50  /* Same comment as above */
51  return new HorizontalLayout(childrenLayouts, 2);
52 }
53 
54 int LayoutEngine::writeInfixExpressionTextInBuffer(const Expression * expression, char * buffer, int bufferSize, int numberOfDigits, const char * operatorName) {
55  if (bufferSize == 0) {
56  return -1;
57  }
58  buffer[bufferSize-1] = 0;
59  int numberOfChar = 0;
60  int numberOfOperands = expression->numberOfOperands();
61  assert(numberOfOperands > 1);
62  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
63  if (expression->operand(0)->needParenthesisWithParent(expression)) {
64  buffer[numberOfChar++] = '(';
65  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
66  }
67  numberOfChar += expression->operand(0)->writeTextInBuffer(buffer+numberOfChar, bufferSize-numberOfChar, numberOfDigits);
68  if (expression->operand(0)->needParenthesisWithParent(expression)) {
69  buffer[numberOfChar++] = ')';
70  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
71  }
72  for (int i=1; i<numberOfOperands; i++) {
73  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
74  numberOfChar += strlcpy(buffer+numberOfChar, operatorName, bufferSize-numberOfChar);
75  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
76  if (expression->operand(i)->needParenthesisWithParent(expression)) {
77  buffer[numberOfChar++] = '(';
78  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
79  }
80  numberOfChar += expression->operand(i)->writeTextInBuffer(buffer+numberOfChar, bufferSize-numberOfChar, numberOfDigits);
81  if (expression->operand(i)->needParenthesisWithParent(expression)) {
82  buffer[numberOfChar++] = ')';
83  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
84  }
85  }
86  buffer[numberOfChar] = 0;
87  return numberOfChar;
88 }
89 
90 int LayoutEngine::writePrefixExpressionTextInBuffer(const Expression * expression, char * buffer, int bufferSize, int numberOfDigits, const char * operatorName) {
91  if (bufferSize == 0) {
92  return -1;
93  }
94  buffer[bufferSize-1] = 0;
95  int numberOfChar = 0;
96  numberOfChar += strlcpy(buffer, operatorName, bufferSize);
97  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
98  buffer[numberOfChar++] = '(';
99  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
100  int numberOfOperands = expression->numberOfOperands();
101  if (numberOfOperands > 0) {
102  numberOfChar += expression->operand(0)->writeTextInBuffer(buffer+numberOfChar, bufferSize-numberOfChar, numberOfDigits);
103  for (int i = 1; i < numberOfOperands; i++) {
104  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
105  buffer[numberOfChar++] = ',';
106  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
107  numberOfChar += expression->operand(i)->writeTextInBuffer(buffer+numberOfChar, bufferSize-numberOfChar, numberOfDigits);
108  }
109  if (numberOfChar >= bufferSize-1) { return bufferSize-1; }
110  }
111  buffer[numberOfChar++] = ')';
112  buffer[numberOfChar] = 0;
113  return numberOfChar;
114 }
115 
116 }
static int writeInfixExpressionTextInBuffer(const Expression *expression, char *buffer, int bufferSize, int numberOfDigits, const char *operatorName)
#define assert(e)
Definition: assert.h:9
size_t strlcpy(char *dst, const char *src, size_t len)
Definition: strlcpy.c:3
size_t strlen(const char *s)
Definition: strlen.c:3
virtual int numberOfOperands() const =0
static ExpressionLayout * createPrefixLayout(const Expression *expression, PrintFloat::Mode floatDisplayMode, Expression::ComplexFormat complexFormat, const char *operatorName)
ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode=PrintFloat::Mode::Default, ComplexFormat complexFormat=ComplexFormat::Default) const
Definition: expression.cpp:244
static ExpressionLayout * createInfixLayout(const Expression *expression, PrintFloat::Mode floatDisplayMode, Expression::ComplexFormat complexFormat, const char *operatorName)
static int writePrefixExpressionTextInBuffer(const Expression *expression, char *buffer, int bufferSize, int numberOfDigits, const char *operatorName)
const Expression * operand(int i) const
Definition: expression.cpp:78
virtual Type type() const =0
virtual int writeTextInBuffer(char *buffer, int bufferSize, int numberOfSignificantDigits=PrintFloat::k_numberOfStoredSignificantDigits) const =0