1. /*
  2. * @(#)BlueprintEngineParser.java 1.10 03/07/25
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.gtk;
  8. import java.io.IOException;
  9. import java.util.ArrayList;
  10. import java.awt.Font;
  11. import java.awt.Insets;
  12. import java.awt.Color;
  13. /**
  14. * A parser for the "blueprint" engine sections in GTK rc theme files.
  15. *
  16. * @author Shannon Hickey
  17. * @version 1.10 07/25/03
  18. */
  19. class BlueprintEngineParser extends GTKEngineParser {
  20. private static final int SYM_IMAGE = GTKScanner.TOKEN_LAST + 1;
  21. private static final int SYM_FUNCTION = SYM_IMAGE + 1;
  22. private static final int SYM_FILE = SYM_FUNCTION + 1;
  23. private static final int SYM_STRETCH = SYM_FILE + 1;
  24. private static final int SYM_RECOLORABLE = SYM_STRETCH + 1;
  25. private static final int SYM_BORDER = SYM_RECOLORABLE + 1;
  26. private static final int SYM_DETAIL = SYM_BORDER + 1;
  27. private static final int SYM_STATE = SYM_DETAIL + 1;
  28. private static final int SYM_SHADOW = SYM_STATE + 1;
  29. private static final int SYM_GAP_SIDE = SYM_SHADOW + 1;
  30. private static final int SYM_GAP_FILE = SYM_GAP_SIDE + 1;
  31. private static final int SYM_GAP_BORDER = SYM_GAP_FILE + 1;
  32. private static final int SYM_GAP_START_FILE = SYM_GAP_BORDER + 1;
  33. private static final int SYM_GAP_START_BORDER = SYM_GAP_START_FILE + 1;
  34. private static final int SYM_GAP_END_FILE = SYM_GAP_START_BORDER + 1;
  35. private static final int SYM_GAP_END_BORDER = SYM_GAP_END_FILE + 1;
  36. private static final int SYM_OVERLAY_FILE = SYM_GAP_END_BORDER + 1;
  37. private static final int SYM_OVERLAY_BORDER = SYM_OVERLAY_FILE + 1;
  38. private static final int SYM_OVERLAY_STRETCH = SYM_OVERLAY_BORDER + 1;
  39. private static final int SYM_ARROW_DIRECTION = SYM_OVERLAY_STRETCH + 1;
  40. private static final int SYM_ORIENTATION = SYM_ARROW_DIRECTION + 1;
  41. private static final int SYM_PARENT_TYPE = SYM_ORIENTATION + 1;
  42. private static final int SYM_COLORIZE_COLOR = SYM_PARENT_TYPE + 1;
  43. private static final int SYM_ICON_COLORIZE = SYM_COLORIZE_COLOR + 1;
  44. private static final int SYM_ICON_COLORIZE_ANCESTOR_TYPE = SYM_ICON_COLORIZE + 1;
  45. private static final int SYM_USE_AS_BKG_MASK = SYM_ICON_COLORIZE_ANCESTOR_TYPE + 1;
  46. private static final int SYM_OVERLAY_RECOLORABLE = SYM_USE_AS_BKG_MASK + 1;
  47. private static final int SYM_OVERLAY_COLORIZE_COLOR = SYM_OVERLAY_RECOLORABLE + 1;
  48. // SYM_D_HLINE and SYM_D_STEPPER are assumed to begin and end the function symbols.
  49. // When adding new symbols, only function symbols should be added between them.
  50. private static final int SYM_D_HLINE = SYM_OVERLAY_COLORIZE_COLOR + 1;
  51. private static final int SYM_D_VLINE = SYM_D_HLINE + 1;
  52. private static final int SYM_D_SHADOW = SYM_D_VLINE + 1;
  53. private static final int SYM_D_POLYGON = SYM_D_SHADOW + 1;
  54. private static final int SYM_D_ARROW = SYM_D_POLYGON + 1;
  55. private static final int SYM_D_DIAMOND = SYM_D_ARROW + 1;
  56. private static final int SYM_D_OVAL = SYM_D_DIAMOND + 1;
  57. private static final int SYM_D_STRING = SYM_D_OVAL + 1;
  58. private static final int SYM_D_BOX = SYM_D_STRING + 1;
  59. private static final int SYM_D_FLAT_BOX = SYM_D_BOX + 1;
  60. private static final int SYM_D_CHECK = SYM_D_FLAT_BOX + 1;
  61. private static final int SYM_D_OPTION = SYM_D_CHECK + 1;
  62. private static final int SYM_D_CROSS = SYM_D_OPTION + 1;
  63. private static final int SYM_D_RAMP = SYM_D_CROSS + 1;
  64. private static final int SYM_D_TAB = SYM_D_RAMP + 1;
  65. private static final int SYM_D_SHADOW_GAP = SYM_D_TAB + 1;
  66. private static final int SYM_D_BOX_GAP = SYM_D_SHADOW_GAP + 1;
  67. private static final int SYM_D_EXTENSION = SYM_D_BOX_GAP + 1;
  68. private static final int SYM_D_FOCUS = SYM_D_EXTENSION + 1;
  69. private static final int SYM_D_SLIDER = SYM_D_FOCUS + 1;
  70. private static final int SYM_D_ENTRY = SYM_D_SLIDER + 1;
  71. private static final int SYM_D_HANDLE = SYM_D_ENTRY + 1;
  72. private static final int SYM_D_LAYOUT = SYM_D_HANDLE + 1;
  73. private static final int SYM_D_BACKGROUND = SYM_D_LAYOUT + 1;
  74. private static final int SYM_D_STEPPER = SYM_D_BACKGROUND + 1;
  75. // end function symbols
  76. private static final int SYM_TRUE = SYM_D_STEPPER + 1;
  77. private static final int SYM_FALSE = SYM_TRUE + 1;
  78. private static final int SYM_TOP = SYM_FALSE + 1;
  79. private static final int SYM_UP = SYM_TOP + 1;
  80. private static final int SYM_BOTTOM = SYM_UP + 1;
  81. private static final int SYM_DOWN = SYM_BOTTOM + 1;
  82. private static final int SYM_LEFT = SYM_DOWN + 1;
  83. private static final int SYM_RIGHT = SYM_LEFT + 1;
  84. private static final int SYM_NORMAL = SYM_RIGHT + 1;
  85. private static final int SYM_ACTIVE = SYM_NORMAL + 1;
  86. private static final int SYM_PRELIGHT = SYM_ACTIVE + 1;
  87. private static final int SYM_SELECTED = SYM_PRELIGHT + 1;
  88. private static final int SYM_INSENSITIVE = SYM_SELECTED + 1;
  89. private static final int SYM_NONE = SYM_INSENSITIVE + 1;
  90. private static final int SYM_IN = SYM_NONE + 1;
  91. private static final int SYM_OUT = SYM_IN + 1;
  92. private static final int SYM_ETCHED_IN = SYM_OUT + 1;
  93. private static final int SYM_ETCHED_OUT = SYM_ETCHED_IN + 1;
  94. private static final int SYM_HORIZONTAL = SYM_ETCHED_OUT + 1;
  95. private static final int SYM_VERTICAL = SYM_HORIZONTAL + 1;
  96. private static final int[] symbolVals = {
  97. SYM_IMAGE, SYM_FUNCTION, SYM_FILE, SYM_STRETCH, SYM_RECOLORABLE,
  98. SYM_BORDER, SYM_DETAIL, SYM_STATE, SYM_SHADOW, SYM_GAP_SIDE,
  99. SYM_GAP_FILE, SYM_GAP_BORDER, SYM_GAP_START_FILE, SYM_GAP_START_BORDER,
  100. SYM_GAP_END_FILE, SYM_GAP_END_BORDER, SYM_OVERLAY_FILE, SYM_OVERLAY_BORDER,
  101. SYM_OVERLAY_STRETCH, SYM_ARROW_DIRECTION, SYM_ORIENTATION,
  102. SYM_PARENT_TYPE, SYM_COLORIZE_COLOR, SYM_ICON_COLORIZE,
  103. SYM_ICON_COLORIZE_ANCESTOR_TYPE, SYM_USE_AS_BKG_MASK,
  104. SYM_OVERLAY_RECOLORABLE, SYM_OVERLAY_COLORIZE_COLOR, SYM_D_HLINE,
  105. SYM_D_VLINE, SYM_D_SHADOW, SYM_D_POLYGON, SYM_D_ARROW, SYM_D_DIAMOND,
  106. SYM_D_OVAL, SYM_D_STRING, SYM_D_BOX, SYM_D_FLAT_BOX, SYM_D_CHECK,
  107. SYM_D_OPTION, SYM_D_CROSS, SYM_D_RAMP, SYM_D_TAB, SYM_D_SHADOW_GAP,
  108. SYM_D_BOX_GAP, SYM_D_EXTENSION, SYM_D_FOCUS, SYM_D_SLIDER, SYM_D_ENTRY,
  109. SYM_D_HANDLE, SYM_D_LAYOUT, SYM_D_BACKGROUND,
  110. SYM_D_STEPPER, SYM_TRUE, SYM_FALSE, SYM_TOP, SYM_UP,
  111. SYM_BOTTOM, SYM_DOWN, SYM_LEFT, SYM_RIGHT, SYM_NORMAL, SYM_ACTIVE,
  112. SYM_PRELIGHT, SYM_SELECTED, SYM_INSENSITIVE, SYM_NONE, SYM_IN, SYM_OUT,
  113. SYM_ETCHED_IN, SYM_ETCHED_OUT, SYM_HORIZONTAL, SYM_VERTICAL
  114. };
  115. private static final String[] symbolNames = {
  116. "image", // SYM_IMAGE
  117. "function", // SYM_FUNCTION
  118. "file", // SYM_FILE
  119. "stretch", // SYM_STRETCH
  120. "recolorable", // SYM_RECOLORABLE
  121. "border", // SYM_BORDER
  122. "detail", // SYM_DETAIL
  123. "state", // SYM_STATE
  124. "shadow", // SYM_SHADOW
  125. "gap_side", // SYM_GAP_SIDE
  126. "gap_file", // SYM_GAP_FILE
  127. "gap_border", // SYM_GAP_BORDER
  128. "gap_start_file", // SYM_GAP_START_FILE
  129. "gap_start_border", // SYM_GAP_START_BORDER
  130. "gap_end_file", // SYM_GAP_END_FILE
  131. "gap_end_border", // SYM_GAP_END_BORDER
  132. "overlay_file", // SYM_OVERLAY_FILE
  133. "overlay_border", // SYM_OVERLAY_BORDER
  134. "overlay_stretch", // SYM_OVERLAY_STRETCH
  135. "arrow_direction", // SYM_ARROW_DIRECTION
  136. "orientation", // SYM_ORIENTATION
  137. "parent_type", // SYM_PARENT_TYPE
  138. "colorize_color", // SYM_COLORIZE_COLOR
  139. "icon_colorize", // SYM_ICON_COLORIZE
  140. "icon_colorize_ancestor_type", // SYM_ICON_COLORIZE_ANCESTOR_TYPE
  141. "use_as_bkg_mask", // SYM_USE_AS_BKG_MASK
  142. "overlay_recolorable", // SYM_OVERLAY_RECOLORABLE
  143. "overlay_colorize_color", // SYM_OVERLAY_COLORIZE_COLOR
  144. "HLINE", // SYM_D_HLINE
  145. "VLINE", // SYM_D_VLINE
  146. "SHADOW", // SYM_D_SHADOW
  147. "POLYGON", // SYM_D_POLYGON
  148. "ARROW", // SYM_D_ARROW
  149. "DIAMOND", // SYM_D_DIAMOND
  150. "OVAL", // SYM_D_OVAL
  151. "STRING", // SYM_D_STRING
  152. "BOX", // SYM_D_BOX
  153. "FLAT_BOX", // SYM_D_FLAT_BOX
  154. "CHECK", // SYM_D_CHECK
  155. "OPTION", // SYM_D_OPTION
  156. "CROSS", // SYM_D_CROSS
  157. "RAMP", // SYM_D_RAMP
  158. "TAB", // SYM_D_TAB
  159. "SHADOW_GAP", // SYM_D_SHADOW_GAP
  160. "BOX_GAP", // SYM_D_BOX_GAP
  161. "EXTENSION", // SYM_D_EXTENSION
  162. "FOCUS", // SYM_D_FOCUS
  163. "SLIDER", // SYM_D_SLIDER
  164. "ENTRY", // SYM_D_ENTRY
  165. "HANDLE", // SYM_D_HANDLE
  166. "LAYOUT", // SYM_D_LAYOUT
  167. "BACKGROUND", // SYM_D_BACKGROUND
  168. "STEPPER", // SYM_D_STEPPER
  169. "TRUE", // SYM_TRUE
  170. "FALSE", // SYM_FALSE
  171. "TOP", // SYM_TOP
  172. "UP", // SYM_UP
  173. "BOTTOM", // SYM_BOTTOM
  174. "DOWN", // SYM_DOWN
  175. "LEFT", // SYM_LEFT
  176. "RIGHT", // SYM_RIGHT
  177. "NORMAL", // SYM_NORMAL
  178. "ACTIVE", // SYM_ACTIVE
  179. "PRELIGHT", // SYM_PRELIGHT
  180. "SELECTED", // SYM_SELECTED
  181. "INSENSITIVE", // SYM_INSENSITIVE
  182. "NONE", // SYM_NONE
  183. "IN", // SYM_IN
  184. "OUT", // SYM_OUT
  185. "ETCHED_IN", // SYM_ETCHED_IN
  186. "ETCHED_OUT", // SYM_ETCHED_OUT
  187. "HORIZONTAL", // SYM_HORIZONTAL
  188. "VERTICAL" // SYM_VERTICAL
  189. };
  190. private static class BlueprintEngineInfo extends GTKParser.EngineInfo {
  191. ArrayList pInfos = new ArrayList();
  192. boolean iconColorize = false;
  193. ArrayList iconAncestorTypes = null;
  194. Color colorizeColor = null;
  195. GTKStyle constructGTKStyle(GTKStyle.GTKStateInfo[] infoArray,
  196. CircularIdentityList props,
  197. Font font,
  198. int xThickness,
  199. int yThickness,
  200. GTKStyle.GTKStockIconInfo[] stockArray) {
  201. BlueprintStyle.Info[] pInfoArray = null;
  202. if (pInfos.size() != 0) {
  203. pInfoArray = new BlueprintStyle.Info[pInfos.size()];
  204. pInfoArray = (BlueprintStyle.Info[])pInfos.toArray(pInfoArray);
  205. }
  206. String[] ancestorArray = null;
  207. if (iconAncestorTypes != null && iconAncestorTypes.size() != 0) {
  208. ancestorArray = new String[iconAncestorTypes.size()];
  209. ancestorArray = (String[])iconAncestorTypes.toArray(ancestorArray);
  210. }
  211. return new BlueprintStyle(infoArray,
  212. props,
  213. font,
  214. xThickness,
  215. yThickness,
  216. stockArray,
  217. pInfoArray,
  218. iconColorize,
  219. ancestorArray,
  220. colorizeColor);
  221. }
  222. }
  223. private GTKScanner scanner;
  224. private GTKParser parser;
  225. private BlueprintEngineInfo engineInfo;
  226. private void registerSymbolsIfNecessary() {
  227. if (scanner.containsSymbol(symbolNames[0])) {
  228. return;
  229. }
  230. for (int i = 0; i < symbolNames.length; i++) {
  231. scanner.addSymbol(symbolNames[i], symbolVals[i]);
  232. }
  233. }
  234. int parse(GTKScanner scanner,
  235. GTKParser parser,
  236. GTKParser.EngineInfo[] retVal) throws IOException {
  237. this.scanner = scanner;
  238. this.parser = parser;
  239. if (retVal[0] == null) {
  240. engineInfo = new BlueprintEngineInfo();
  241. } else {
  242. engineInfo = (BlueprintEngineInfo)retVal[0];
  243. }
  244. int oldScope = scanner.setScope(uniqueScopeID);
  245. registerSymbolsIfNecessary();
  246. BlueprintStyle.Info info[] = new BlueprintStyle.Info[1];
  247. int token;
  248. token = scanner.peekNextToken();
  249. while (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  250. info[0] = null;
  251. switch(token) {
  252. case SYM_IMAGE:
  253. token = parseImage(info);
  254. break;
  255. case SYM_COLORIZE_COLOR:
  256. Color[] col = new Color[1];
  257. token = parseColorizeColor(col);
  258. if (token == GTKScanner.TOKEN_NONE) {
  259. engineInfo.colorizeColor = col[0];
  260. }
  261. break;
  262. case SYM_ICON_COLORIZE:
  263. token = parseIconColorize(engineInfo);
  264. break;
  265. case SYM_ICON_COLORIZE_ANCESTOR_TYPE:
  266. // consume token
  267. scanner.getToken();
  268. if (engineInfo.iconAncestorTypes == null) {
  269. engineInfo.iconAncestorTypes = new ArrayList();
  270. }
  271. token = parseStringList(engineInfo.iconAncestorTypes);
  272. break;
  273. default:
  274. scanner.getToken();
  275. token = GTKScanner.TOKEN_RIGHT_CURLY;
  276. break;
  277. }
  278. if (token != GTKScanner.TOKEN_NONE) {
  279. return token;
  280. }
  281. if (info[0] != null) {
  282. engineInfo.pInfos.add(info[0]);
  283. }
  284. token = scanner.peekNextToken();
  285. }
  286. scanner.getToken();
  287. retVal[0] = engineInfo;
  288. scanner.setScope(oldScope);
  289. return GTKScanner.TOKEN_NONE;
  290. }
  291. private int parseImage(BlueprintStyle.Info[] retVal) throws IOException {
  292. int token;
  293. token = scanner.getToken();
  294. if (token != SYM_IMAGE) {
  295. return SYM_IMAGE;
  296. }
  297. token = scanner.getToken();
  298. if (token != GTKScanner.TOKEN_LEFT_CURLY) {
  299. return GTKScanner.TOKEN_LEFT_CURLY;
  300. }
  301. BlueprintStyle.Info info = new BlueprintStyle.Info();
  302. // to hold the return value from parseFile
  303. String[] fileName = new String[1];
  304. // to hold the return value from parseStretch
  305. // and parseRecolorable
  306. boolean[] bool = new boolean[1];
  307. // to hold the return value from parseBorder
  308. Insets[] insets = new Insets[1];
  309. // to hold the return value from parseColorizeColor
  310. Color[] col = new Color[1];
  311. token = scanner.peekNextToken();
  312. while (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  313. switch(token) {
  314. case SYM_FUNCTION:
  315. token = parseFunction(info);
  316. break;
  317. case SYM_RECOLORABLE:
  318. token = parseRecolorable(bool);
  319. if (token == GTKScanner.TOKEN_NONE) {
  320. info.recolorable = bool[0];
  321. }
  322. break;
  323. case SYM_OVERLAY_RECOLORABLE:
  324. token = parseRecolorable(bool);
  325. if (token == GTKScanner.TOKEN_NONE) {
  326. info.overlayRecolorable = bool[0];
  327. }
  328. break;
  329. case SYM_DETAIL:
  330. token = parseDetail(info);
  331. break;
  332. case SYM_STATE:
  333. token = parseState(info);
  334. break;
  335. case SYM_SHADOW:
  336. token = parseShadow(info);
  337. break;
  338. case SYM_GAP_SIDE:
  339. token = parseGapSide(info);
  340. break;
  341. case SYM_ARROW_DIRECTION:
  342. token = parseArrowDirection(info);
  343. break;
  344. case SYM_ORIENTATION:
  345. token = parseOrientation(info);
  346. break;
  347. case SYM_FILE:
  348. token = parseFile(fileName);
  349. if (token == GTKScanner.TOKEN_NONE) {
  350. info.image = fileName[0];
  351. }
  352. break;
  353. case SYM_BORDER:
  354. token = parseBorder(insets);
  355. if (token == GTKScanner.TOKEN_NONE) {
  356. info.fileInsets = insets[0];
  357. }
  358. break;
  359. case SYM_STRETCH:
  360. token = parseStretch(bool);
  361. if (token == GTKScanner.TOKEN_NONE) {
  362. info.stretch = bool[0];
  363. }
  364. break;
  365. case SYM_GAP_FILE:
  366. token = parseFile(fileName);
  367. if (token == GTKScanner.TOKEN_NONE) {
  368. info.gapImage = fileName[0];
  369. }
  370. break;
  371. case SYM_GAP_BORDER:
  372. token = parseBorder(insets);
  373. if (token == GTKScanner.TOKEN_NONE) {
  374. info.gapInsets = insets[0];
  375. }
  376. break;
  377. case SYM_GAP_START_FILE:
  378. token = parseFile(fileName);
  379. if (token == GTKScanner.TOKEN_NONE) {
  380. info.gapStartImage = fileName[0];
  381. }
  382. break;
  383. case SYM_GAP_START_BORDER:
  384. token = parseBorder(insets);
  385. if (token == GTKScanner.TOKEN_NONE) {
  386. info.gapStartInsets = insets[0];
  387. }
  388. break;
  389. case SYM_GAP_END_FILE:
  390. token = parseFile(fileName);
  391. if (token == GTKScanner.TOKEN_NONE) {
  392. info.gapEndImage = fileName[0];
  393. }
  394. break;
  395. case SYM_GAP_END_BORDER:
  396. token = parseBorder(insets);
  397. if (token == GTKScanner.TOKEN_NONE) {
  398. info.gapEndInsets = insets[0];
  399. }
  400. break;
  401. case SYM_OVERLAY_FILE:
  402. token = parseFile(fileName);
  403. if (token == GTKScanner.TOKEN_NONE) {
  404. info.overlayImage = fileName[0];
  405. }
  406. break;
  407. case SYM_OVERLAY_BORDER:
  408. token = parseBorder(insets);
  409. if (token == GTKScanner.TOKEN_NONE) {
  410. info.overlayInsets = insets[0];
  411. }
  412. break;
  413. case SYM_OVERLAY_STRETCH:
  414. token = parseStretch(bool);
  415. if (token == GTKScanner.TOKEN_NONE) {
  416. info.overlayStretch = bool[0];
  417. }
  418. break;
  419. case SYM_PARENT_TYPE:
  420. // consume token
  421. scanner.getToken();
  422. if (info.parentTypeList == null) {
  423. info.parentTypeList = new ArrayList();
  424. }
  425. token = parseStringList(info.parentTypeList);
  426. break;
  427. case SYM_COLORIZE_COLOR:
  428. token = parseColorizeColor(col);
  429. if (token == GTKScanner.TOKEN_NONE) {
  430. info.colorizeColor = col[0];
  431. }
  432. break;
  433. case SYM_OVERLAY_COLORIZE_COLOR:
  434. token = parseColorizeColor(col);
  435. if (token == GTKScanner.TOKEN_NONE) {
  436. info.overlayColorizeColor = col[0];
  437. }
  438. break;
  439. case SYM_USE_AS_BKG_MASK:
  440. token = parseUseAsBkgMask(info);
  441. break;
  442. default:
  443. scanner.getToken();
  444. token = GTKScanner.TOKEN_RIGHT_CURLY;
  445. break;
  446. }
  447. if (token != GTKScanner.TOKEN_NONE) {
  448. return token;
  449. }
  450. token = scanner.peekNextToken();
  451. }
  452. token = scanner.getToken();
  453. if (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  454. return GTKScanner.TOKEN_RIGHT_CURLY;
  455. }
  456. // PENDING(shannonh) - may want to do some validation of the
  457. // info before we return it
  458. retVal[0] = info;
  459. return GTKScanner.TOKEN_NONE;
  460. }
  461. private int parseFunction(BlueprintStyle.Info info) throws IOException {
  462. int token;
  463. token = scanner.getToken();
  464. if (token != SYM_FUNCTION) {
  465. return SYM_FUNCTION;
  466. }
  467. token = scanner.getToken();
  468. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  469. return GTKScanner.TOKEN_EQUAL_SIGN;
  470. }
  471. token = scanner.getToken();
  472. if (token >= SYM_D_HLINE && token <= SYM_D_STEPPER) {
  473. info.setFunction(symbolNames[token - SYM_IMAGE]);
  474. }
  475. // PENDING(shannonh) - should we complain if not a valid function?
  476. return GTKScanner.TOKEN_NONE;
  477. }
  478. private int parseRecolorable(boolean[] retVal) throws IOException {
  479. int token;
  480. scanner.getToken();
  481. token = scanner.getToken();
  482. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  483. return GTKScanner.TOKEN_EQUAL_SIGN;
  484. }
  485. token = scanner.getToken();
  486. if (token == SYM_TRUE) {
  487. retVal[0] = true;
  488. } else if (token == SYM_FALSE) {
  489. retVal[0] = false;
  490. } else {
  491. return SYM_TRUE;
  492. }
  493. return GTKScanner.TOKEN_NONE;
  494. }
  495. private int parseDetail(BlueprintStyle.Info info) throws IOException {
  496. int token;
  497. token = scanner.getToken();
  498. if (token != SYM_DETAIL) {
  499. return SYM_DETAIL;
  500. }
  501. token = scanner.getToken();
  502. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  503. return GTKScanner.TOKEN_EQUAL_SIGN;
  504. }
  505. token = scanner.getToken();
  506. if (token != GTKScanner.TOKEN_STRING) {
  507. return GTKScanner.TOKEN_STRING;
  508. }
  509. info.setDetail(scanner.currValue.stringVal);
  510. return GTKScanner.TOKEN_NONE;
  511. }
  512. private int parseState(BlueprintStyle.Info info) throws IOException {
  513. int token;
  514. token = scanner.getToken();
  515. if (token != SYM_STATE) {
  516. return SYM_STATE;
  517. }
  518. token = scanner.getToken();
  519. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  520. return GTKScanner.TOKEN_EQUAL_SIGN;
  521. }
  522. token = scanner.getToken();
  523. switch(token) {
  524. case SYM_NORMAL:
  525. info.componentState = SynthConstants.ENABLED;
  526. break;
  527. case SYM_ACTIVE:
  528. info.componentState = SynthConstants.PRESSED;
  529. break;
  530. case SYM_PRELIGHT:
  531. info.componentState = SynthConstants.MOUSE_OVER;
  532. break;
  533. case SYM_SELECTED:
  534. info.componentState = SynthConstants.SELECTED;
  535. break;
  536. case SYM_INSENSITIVE:
  537. info.componentState = SynthConstants.DISABLED;
  538. break;
  539. default:
  540. return SYM_NORMAL;
  541. }
  542. return GTKScanner.TOKEN_NONE;
  543. }
  544. private int parseShadow(BlueprintStyle.Info info) throws IOException {
  545. int token;
  546. token = scanner.getToken();
  547. if (token != SYM_SHADOW) {
  548. return SYM_SHADOW;
  549. }
  550. token = scanner.getToken();
  551. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  552. return GTKScanner.TOKEN_EQUAL_SIGN;
  553. }
  554. token = scanner.getToken();
  555. switch(token) {
  556. case SYM_NONE:
  557. info.shadow = GTKConstants.SHADOW_NONE;
  558. break;
  559. case SYM_IN:
  560. info.shadow = GTKConstants.SHADOW_IN;
  561. break;
  562. case SYM_OUT:
  563. info.shadow = GTKConstants.SHADOW_OUT;
  564. break;
  565. case SYM_ETCHED_IN:
  566. info.shadow = GTKConstants.SHADOW_ETCHED_IN;
  567. break;
  568. case SYM_ETCHED_OUT:
  569. info.shadow = GTKConstants.SHADOW_ETCHED_OUT;
  570. break;
  571. default:
  572. return SYM_NONE;
  573. }
  574. return GTKScanner.TOKEN_NONE;
  575. }
  576. private int parseGapSide(BlueprintStyle.Info info) throws IOException {
  577. int token;
  578. token = scanner.getToken();
  579. if (token != SYM_GAP_SIDE) {
  580. return SYM_GAP_SIDE;
  581. }
  582. token = scanner.getToken();
  583. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  584. return GTKScanner.TOKEN_EQUAL_SIGN;
  585. }
  586. token = scanner.getToken();
  587. switch(token) {
  588. case SYM_TOP:
  589. info.gapSide = GTKConstants.TOP;
  590. break;
  591. case SYM_BOTTOM:
  592. info.gapSide = GTKConstants.BOTTOM;
  593. break;
  594. case SYM_LEFT:
  595. info.gapSide = GTKConstants.LEFT;
  596. break;
  597. case SYM_RIGHT:
  598. info.gapSide = GTKConstants.RIGHT;
  599. break;
  600. default:
  601. return SYM_TOP;
  602. }
  603. return GTKScanner.TOKEN_NONE;
  604. }
  605. private int parseArrowDirection(BlueprintStyle.Info info) throws IOException {
  606. int token;
  607. token = scanner.getToken();
  608. if (token != SYM_ARROW_DIRECTION) {
  609. return SYM_ARROW_DIRECTION;
  610. }
  611. token = scanner.getToken();
  612. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  613. return GTKScanner.TOKEN_EQUAL_SIGN;
  614. }
  615. token = scanner.getToken();
  616. switch(token) {
  617. case SYM_UP:
  618. info.arrowDirection = GTKConstants.ARROW_UP;
  619. break;
  620. case SYM_DOWN:
  621. info.arrowDirection = GTKConstants.ARROW_DOWN;
  622. break;
  623. case SYM_LEFT:
  624. info.arrowDirection = GTKConstants.ARROW_LEFT;
  625. break;
  626. case SYM_RIGHT:
  627. info.arrowDirection = GTKConstants.ARROW_RIGHT;
  628. break;
  629. default:
  630. return SYM_UP;
  631. }
  632. return GTKScanner.TOKEN_NONE;
  633. }
  634. private int parseOrientation(BlueprintStyle.Info info) throws IOException {
  635. int token;
  636. token = scanner.getToken();
  637. if (token != SYM_ORIENTATION) {
  638. return SYM_ORIENTATION;
  639. }
  640. token = scanner.getToken();
  641. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  642. return GTKScanner.TOKEN_EQUAL_SIGN;
  643. }
  644. token = scanner.getToken();
  645. switch(token) {
  646. case SYM_HORIZONTAL:
  647. info.orientation = GTKConstants.HORIZONTAL;
  648. break;
  649. case SYM_VERTICAL:
  650. info.orientation = GTKConstants.VERTICAL;
  651. break;
  652. default:
  653. return SYM_HORIZONTAL;
  654. }
  655. return GTKScanner.TOKEN_NONE;
  656. }
  657. private int parseFile(String[] retVal) throws IOException {
  658. int token;
  659. token = scanner.getToken();
  660. token = scanner.getToken();
  661. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  662. return GTKScanner.TOKEN_EQUAL_SIGN;
  663. }
  664. token = scanner.getToken();
  665. if (token != GTKScanner.TOKEN_STRING) {
  666. return GTKScanner.TOKEN_STRING;
  667. }
  668. retVal[0] = parser.resolvePixmapPath(scanner.currValue.stringVal);
  669. return GTKScanner.TOKEN_NONE;
  670. }
  671. private int parseStretch(boolean[] retVal) throws IOException {
  672. int token;
  673. token = scanner.getToken();
  674. token = scanner.getToken();
  675. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  676. return GTKScanner.TOKEN_EQUAL_SIGN;
  677. }
  678. token = scanner.getToken();
  679. switch(token) {
  680. case SYM_TRUE:
  681. retVal[0] = true;
  682. break;
  683. case SYM_FALSE:
  684. retVal[0] = false;
  685. break;
  686. default:
  687. return SYM_TRUE;
  688. }
  689. return GTKScanner.TOKEN_NONE;
  690. }
  691. private int parseBorder(Insets[] retVal) throws IOException {
  692. int left = 0;
  693. int right = 0;
  694. int top = 0;
  695. int bottom = 0;
  696. scanner.getToken();
  697. if (scanner.getToken() != GTKScanner.TOKEN_EQUAL_SIGN) {
  698. return GTKScanner.TOKEN_EQUAL_SIGN;
  699. }
  700. if (scanner.getToken() != GTKScanner.TOKEN_LEFT_CURLY) {
  701. return GTKScanner.TOKEN_LEFT_CURLY;
  702. }
  703. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  704. return GTKScanner.TOKEN_INT;
  705. }
  706. left = (int)scanner.currValue.longVal;
  707. if (scanner.getToken() != GTKScanner.TOKEN_COMMA) {
  708. return GTKScanner.TOKEN_COMMA;
  709. }
  710. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  711. return GTKScanner.TOKEN_INT;
  712. }
  713. right = (int)scanner.currValue.longVal;
  714. if (scanner.getToken() != GTKScanner.TOKEN_COMMA) {
  715. return GTKScanner.TOKEN_COMMA;
  716. }
  717. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  718. return GTKScanner.TOKEN_INT;
  719. }
  720. top = (int)scanner.currValue.longVal;
  721. if (scanner.getToken() != GTKScanner.TOKEN_COMMA) {
  722. return GTKScanner.TOKEN_COMMA;
  723. }
  724. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  725. return GTKScanner.TOKEN_INT;
  726. }
  727. bottom = (int)scanner.currValue.longVal;
  728. if (scanner.getToken() != GTKScanner.TOKEN_RIGHT_CURLY) {
  729. return GTKScanner.TOKEN_RIGHT_CURLY;
  730. }
  731. retVal[0] = new Insets(top, left, bottom, right);
  732. return GTKScanner.TOKEN_NONE;
  733. }
  734. private int parseColorizeColor(Color[] retVal) throws IOException {
  735. int token;
  736. scanner.getToken();
  737. token = scanner.getToken();
  738. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  739. return GTKScanner.TOKEN_EQUAL_SIGN;
  740. }
  741. token = scanner.getToken();
  742. switch(token) {
  743. case GTKScanner.TOKEN_LEFT_CURLY:
  744. int red;
  745. int green;
  746. int blue;
  747. int alpha = 255;
  748. token = scanner.getToken();
  749. if (token == GTKScanner.TOKEN_INT) {
  750. red = intColorVal(scanner.currValue.longVal);
  751. } else if (token == GTKScanner.TOKEN_FLOAT) {
  752. red = intColorVal(scanner.currValue.doubleVal);
  753. } else {
  754. return GTKScanner.TOKEN_FLOAT;
  755. }
  756. token = scanner.getToken();
  757. if (token != GTKScanner.TOKEN_COMMA) {
  758. return GTKScanner.TOKEN_COMMA;
  759. }
  760. token = scanner.getToken();
  761. if (token == GTKScanner.TOKEN_INT) {
  762. green = intColorVal(scanner.currValue.longVal);
  763. } else if (token == GTKScanner.TOKEN_FLOAT) {
  764. green = intColorVal(scanner.currValue.doubleVal);
  765. } else {
  766. return GTKScanner.TOKEN_FLOAT;
  767. }
  768. token = scanner.getToken();
  769. if (token != GTKScanner.TOKEN_COMMA) {
  770. return GTKScanner.TOKEN_COMMA;
  771. }
  772. token = scanner.getToken();
  773. if (token == GTKScanner.TOKEN_INT) {
  774. blue = intColorVal(scanner.currValue.longVal);
  775. } else if (token == GTKScanner.TOKEN_FLOAT) {
  776. blue = intColorVal(scanner.currValue.doubleVal);
  777. } else {
  778. return GTKScanner.TOKEN_FLOAT;
  779. }
  780. token = scanner.getToken();
  781. if (token == GTKScanner.TOKEN_COMMA) {
  782. token = scanner.getToken();
  783. if (token == GTKScanner.TOKEN_INT) {
  784. alpha = intColorVal(scanner.currValue.longVal);
  785. } else if (token == GTKScanner.TOKEN_FLOAT) {
  786. alpha = intColorVal(scanner.currValue.doubleVal);
  787. } else {
  788. return GTKScanner.TOKEN_FLOAT;
  789. }
  790. token = scanner.getToken();
  791. }
  792. if (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  793. return GTKScanner.TOKEN_RIGHT_CURLY;
  794. }
  795. retVal[0] = new Color(red, green, blue, alpha);
  796. break;
  797. case GTKScanner.TOKEN_STRING:
  798. Color color = parseColorString(scanner.currValue.stringVal);
  799. if (color == null) {
  800. scanner.printMessage("Invalid color constant '" +
  801. scanner.currValue.stringVal
  802. + "'", false);
  803. return GTKScanner.TOKEN_STRING;
  804. }
  805. retVal[0] = color;
  806. break;
  807. default:
  808. return GTKScanner.TOKEN_STRING;
  809. }
  810. return GTKScanner.TOKEN_NONE;
  811. }
  812. private static Color parseColorString(String str) {
  813. if (str.charAt(0) == '#') {
  814. str = str.substring(1);
  815. int i = str.length();
  816. if (i < 3 || i > 12 || (i % 3) != 0) {
  817. return null;
  818. }
  819. i /= 3;
  820. int r;
  821. int g;
  822. int b;
  823. try {
  824. r = Integer.parseInt(str.substring(0, i), 16);
  825. g = Integer.parseInt(str.substring(i, i * 2), 16);
  826. b = Integer.parseInt(str.substring(i * 2, i * 3), 16);
  827. } catch (NumberFormatException nfe) {
  828. return null;
  829. }
  830. if (i == 4) {
  831. return new Color(r / 65535.0f, g / 65535.0f, b / 65535.0f);
  832. } else if (i == 1) {
  833. return new Color(r / 15.0f, g / 15.0f, b / 15.0f);
  834. } else if (i == 2) {
  835. return new Color(r, g, b);
  836. } else {
  837. return new Color(r / 4095.0f, g / 4095.0f, b / 4095.0f);
  838. }
  839. } else {
  840. return XColors.lookupColor(str);
  841. }
  842. }
  843. private static int intColorVal(long col) {
  844. int color = (int)Math.max(Math.min(col, 255), 0);
  845. return color;
  846. }
  847. private static int intColorVal(double col) {
  848. float color = (float)Math.max(Math.min(col, 1.0f), 0.0f);
  849. return (int)(color * 255);
  850. }
  851. private int parseIconColorize(BlueprintEngineInfo engineInfo) throws IOException {
  852. int token;
  853. token = scanner.getToken();
  854. if (token != SYM_ICON_COLORIZE) {
  855. return SYM_ICON_COLORIZE;
  856. }
  857. token = scanner.getToken();
  858. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  859. return GTKScanner.TOKEN_EQUAL_SIGN;
  860. }
  861. token = scanner.getToken();
  862. if (token == SYM_TRUE) {
  863. engineInfo.iconColorize = true;
  864. } else if (token == SYM_FALSE) {
  865. engineInfo.iconColorize = false;
  866. } else {
  867. return SYM_TRUE;
  868. }
  869. return GTKScanner.TOKEN_NONE;
  870. }
  871. /**
  872. * Helper method for parsing string list assignments such as the following:
  873. * = {"FOO", "BAR", "SJH"}
  874. * The scanner is expected to start returning tokens at the equal sign when
  875. * this method is invoked. It will parse the strings in the list into the
  876. * given <code>ArrayList</code> parameter.
  877. *
  878. * NOTE: The <code>Strings</code> that are added to the
  879. * <code>ArrayList</code> will have been <code>intern()</code>ed
  880. * first.
  881. *
  882. * @return <code>GTKScanner.TOKEN_NONE</code> if the parse was successful,
  883. * otherwise the token that was expected but not received.
  884. */
  885. private int parseStringList(ArrayList list) throws IOException {
  886. int token;
  887. token = scanner.getToken();
  888. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  889. return GTKScanner.TOKEN_EQUAL_SIGN;
  890. }
  891. token = scanner.getToken();
  892. if (token != GTKScanner.TOKEN_LEFT_CURLY) {
  893. return GTKScanner.TOKEN_LEFT_CURLY;
  894. }
  895. token = scanner.getToken();
  896. while (token == GTKScanner.TOKEN_STRING) {
  897. list.add(scanner.currValue.stringVal.intern());
  898. token = scanner.getToken();
  899. if (token == GTKScanner.TOKEN_RIGHT_CURLY) {
  900. continue;
  901. }
  902. if (token != GTKScanner.TOKEN_COMMA) {
  903. return GTKScanner.TOKEN_COMMA;
  904. }
  905. token = scanner.getToken();
  906. }
  907. if (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  908. return GTKScanner.TOKEN_RIGHT_CURLY;
  909. }
  910. return GTKScanner.TOKEN_NONE;
  911. }
  912. private int parseUseAsBkgMask(BlueprintStyle.Info info) throws IOException {
  913. int token;
  914. token = scanner.getToken();
  915. if (token != SYM_USE_AS_BKG_MASK) {
  916. return SYM_USE_AS_BKG_MASK;
  917. }
  918. token = scanner.getToken();
  919. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  920. return GTKScanner.TOKEN_EQUAL_SIGN;
  921. }
  922. token = scanner.getToken();
  923. switch(token) {
  924. case SYM_TRUE:
  925. info.useAsBkgMask = true;
  926. break;
  927. case SYM_FALSE:
  928. info.useAsBkgMask = false;
  929. break;
  930. default:
  931. return SYM_TRUE;
  932. }
  933. return GTKScanner.TOKEN_NONE;
  934. }
  935. }